For a school assignment, I have been tasked with making a simple codebreaker game using the functions and prototypes provided. You should be able to input the length and difficulty of the code, and type in numbers to make your guess. The part I'm having trouble with is determining the Perfect and Imperfect matches. The program needs to tell the player how many perfect matches (correct number in the correct place) their guess had, and then reveal the perfect matches. The latter I have correct, but the former is only returning with 56 perfect matches when I test it. And I don't really know where to start with the Imperfect matches section, and how I can get it to skip perfect matches. Is there any way I can do this without strings?
Keep in mind, this is a section of the code, not the entire program. It's in this section that things are breaking.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void GetGuess(int guess[], int length) {
int i;
printf("\n\nPlease input your guesses.\n");
for(i = 0; i < length; i++){
scanf("%d", &guess[i]);
}
return;
}
void ProcessGuess(int hidelist[], int showlist[], int length, int guess[]) {
int i;
int perfectsum, imperfectsum;
for(i = 0; i < length; i++){
if(guess[i] == hidelist[i]){
PerfectMatches(hidelist, guess, length);
showlist[i] = guess[i];
}
else{
ImperfectMatches(hidelist, guess, length);
}
}
printf("You have %d perfect matches and %d imperfect matches!\n\n", perfectsum, imperfectsum);
return;
}
int PerfectMatches(int hidelist[], int guess[], int length) {
int i;
int perfectsum = 0;
for(i = 0; i < length; i++){
if(guess[i] == hidelist[i]){
perfectsum++;
}
}
return perfectsum;
}
int ImperfectMatches(int hidelist[], int guess[], int length) {
int i, j;
int imperfectsum = 0;
for(i = 0; i < length; i++){
for(j = 0; j < length; j++){
if(i != j){
if(hidelist[i] == guess[j]){
imperfectsum++;
break;
}
}
}
}
return imperfectsum;
}
void copyArray(int dest[], int source[], int length) {
}
Firstly in your function ProcessGuess you didn't get the return of the PerfectMatches and ImperfectMatches functions. So your perfectsum and imperfectsum aren't correct.
Then concerning the Imperfect Matches section you can use the PerfectMatches function but using != instead of == (if I understood the rules correctly)
Related
I am working on an old exam and the problems states that a given array (int zahlen[]={1,4,5,1,5,7,9,2,3,4}) has values that are the same. The task is to replace the values that are the same with '-1'. After each replacement, a given variable, count, has to be increased by one.
My problem is that the variable count is two-times higher than normal (In this case there are only 3 of the same numbers and the variable shows 6.)
The function is called array_unique. I am would be grateful for a brief explanation of my mistake.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("chcp 1252");
int zahlen[]={1,4,5,1,5,7,9,2,3,4};
int len = sizeof(zahlen)/sizeof(int);
int erg = array_unique(zahlen,len);
printf("Es wurden %d doppelte Zahlen gelöscht: \n",erg);
printf("Das Array hat nun folgende Werte: ");
printArrayUnique(zahlen,len);
return 0;
}
void printArrayUnique(int *array, int len){
for(int i=0; i<len; i++){
if(array[i]!=-1){
printf("%d ",array[i]);
}
}
}
int array_unique(int *array, int len){
int count=0;
for(int i=0; i<len;i++){
for(int j=i+1; j<len;j++){
if(array[i]==array[j]){
array[j] = -1;
count++;
}
}
}
return count;
}
I have not figured out any other solution to fix the faulty value of count.
The issue is due to the fact that your are counting duplicates more than once; so, when you have found a duplicate entry, you correctly replace that with -1 but then, later in the loops, you will be (potentially, at least) comparing two or more of those -1 values.
Just add a check that either value is not -1 (along with the test for equality) before incrementing the count variable:
int array_unique(int* array, int len)
{
int count = 0;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (array[i] == array[j] && array[j] != -1) {
array[j] = -1;
count++;
}
}
}
return count;
}
Note also that, as mentioned in the comments, you really do need declarations of your functions before you use them. Add the following two lines before the main function:
void printArrayUnique(int* array, int len);
int array_unique(int* array, int len);
If this has any error, kindly mention it. Because I may figure out some future consequences
#include<stdio.h>
int main()
{
int a[]={1,2,3,4,5,5,4,3,4,5},count[10]={0},i;
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
{
int x;
x=a[i];
count[x]=count[x]+1;
}
for(i=0;i<sizeof(count)/sizeof(count[0]);i++)
{
if(count[i]!=0)
{
printf("\n %d:%d",i,count[i]);
}
}
}
Generally? No. In this specific case? Maybe.
Instead of sizeof(a)/sizeof(a[0]), use a macro to get the array size.
Dont declare/initialize a loop variable and two arrays in one line.
You will get out of bounds issues as soon as a contains a number that is bigger than the length of count - 1 or smaller than 0.
I would do something like the following:
#include <stdio.h>
#include <string.h>
#define ARRAY_COUNT(array) (sizeof(array)/sizeof(array[0]))
void GetCountOfNumberInArray(int intArray[],
unsigned int intArraySize,
int numbersToCount[],
unsigned int numberCount[],
unsigned int numbersToCountSize){
memset(numberCount, 0, numbersToCountSize * sizeof(numbersToCountSize));
unsigned int count = 0;
for(unsigned int i = 0; i < intArraySize; i++){
for(int j = 0; j < numbersToCountSize; j++){
if(numbersToCount[j] == intArray[i]){
numberCount[j]++;
break;
}
}
}
}
int main(int argc, char *argv[]){
int intArray[] = {1,2,3,4,5,5,4,3,2,1};
int numbersToCount[] = {1,2,3,4,5,6,7,8,9,10};
unsigned int numberCount[ARRAY_COUNT(numbersToCount)];
GetCountOfNumberInArray(intArray,
ARRAY_COUNT(intArray),
numbersToCount,
numberCount,
ARRAY_COUNT(numbersToCount));
for(unsigned int i = 0; i < ARRAY_COUNT(numbersToCount); i++){
printf("number %i appears %u times in the array\n", numbersToCount[i], numberCount[i]);
}
}
That way you get a universal function to count a set of numbers in an array that still works similar to your original solution.
In the below code, I am saving and printing two vectors. This means I have created each function —scanf() and printf()— twice even though they are the same apart from the vector name they operate. How could I have only one scanf() and printf() functions, and still save and print as many vectors as I want? N.b. In this case, I am only working with static vectors.
#include <stdio.h>
int scanning_first_vector(int *vector1);
int printing_first_vector(int *vector1);
int scanning_first_vector(int *vector2);
int printing_first_vector(int *vector2);
int main()
{
int vector1[5], vector2[5];
printf("Please enter the first vector.\n");
scanning_first_vector(vector1);
printing_first_vector(vector1);
printf("\nPlease enter the second vector.\n");
scanning_first_vector(vector2);
printing_first_vector(vector2);
return 0;
}
int scanning_first_vector(int *vector1)
{
int i;
for (i = 0; i < 5; ++i)
{
scanf("%d", &vector1[i]);
}
return 0;
}
int printing_first_vector(int *vector1)
{
int i;
for (i = 0; i < 5; ++i)
{
printf(" %d ", vector1[i]);
}
return 0;
}
int scanning_second_vector(int *vector2)
{
int i;
for (i = 0; i < 5; ++i)
{
scanf("%d", &vector2[i]);
}
return 0;
}
int printing_second_vector(int *vector2)
{
int i;
for (i = 0; i < 5; ++i)
{
printf(" %d \n", vector2[i]);
}
return 0;
}
I think I just did below the leaner version of the code after reading the comments — thank you, guys! :-) I understand now that I can use the same function & I only need to make sure I give distinctive names to the vectors in the main() function. It works well, but it would also be awesome to get confirmation that the way the code is done here is as lean & good as it can get :-) Thank you!
#include <stdio.h>
int scanning_vector(int *vector);
int printing_vector(int *vector);
int main()
{
int vector1[5], vector2[5];
printf("Please enter the first vector:\n");
scanning_vector(vector1);
printing_vector(vector1);
printf("\nPlease enter the second vector:\n");
scanning_vector(vector2);
printing_vector(vector2);
return 0;
}
int scanning_vector(int *vector)
{
int i;
for (i = 0; i < 5; ++i)
{
scanf("%d", &vector[i]);
}
return 0;
}
int printing_vector(int *vector)
{
int i;
for (i = 0; i < 5; ++i)
{
printf(" %d ", vector[i]);
}
return 0;
}
My issue is that I am getting segmentation fault (core dumped) each time I try, I have yet to clean up my code, but I am stumped.
I must enter the values in with the compiler e.g "./filename 0 100" whereby 0 is min and 100 is max.
It must then fill the array of 10 elements with random numbers (0-100). I am so close, just can't fathom the main function.
Also, how can I print the array {0,1,2,3} in format "[0,1,2,3]" including the commas, without it looking like "[0,1,2,3, ]"
#include <stdlib.h>
#include <stdio.h>
int getRandom(int min, int max);
void fillArray(int data[], int size, int min, int max);
void printArray(int data[], int size);
int main(int argc, char *argv[]) {
int a;
int b;
if (argc>=3){
a = atoi(argv[1]);
b = atoi(argv[2]);
int arr[10];
printf("\t An array with random values from 0 to 100 \n");
fillArray(arr,10 ,a, b);
printArray(arr, 10);
} else {
printf("Incorrect number of arguments - please call with assignment min max\n");
}
return 0;
}
int getRandom(int min, int max) {
int result = 0;
int low = 0;
int high = 0;
if (min<max) {
low = min;
high = max+1;
} else {
low = max + 1;
high = min;
}
result = (rand() % (high-low)) + low;
return result;
}
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){
data[i] = getRandom(min,max);
}
}
void printArray(int data[], int size){
int i;
printf("[");
for(i=0; i<size; i++){
printf("%d,", data[i]);
}
printf("]");
}
I agree with #Steve Friedl that the main problem with your program lies in the fillArray function. There i should run from 0 to size.
As for your second question, testing whether you're printing the last number helps to suppress the unwanted comma:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d", data[i]);
if (i < size - 1)
printf(",");
}
printf("]");
}
If you prefer a more compact solution (although with an optimizing compiler there's not really a difference), you could write it as:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d%c", data[i], i < size-1 ? ',' : ']');
}
}
Also, in your main function, you should include a and b in your printing:
printf("\t An array with random values from %d to %d \n", a, b);
I believe this is blowing things up for you:
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){ // <-- HERE
data[i] = getRandom(min,max);
}
}
The calling function allocates 10 items in the arr array, and that's passed as the size parameter, but you're not using that parameter to limit filling up the array. If the max value is 100, then it's trying to fill one hundred slots instead of just ten.
for (i = 0; i < size; i++)
data[i] = getRandom(min,max);
should fix at least this issue.
EDIT: The comma thing, I prefer to add commas before the items unless this is the first. In this case it doesn't matter much, but it's more general, especially for variable-length lists where you don't know you're at the end until you get there. Augmenting the helpful response from #JohanC :
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
if (i > 0) printf(",");
printf("%d", data[i]);
}
printf("]");
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have been tried to write radix sort in c.when i run my code with the static array it works well. but when i am trying to take random inputs from file it gives me an "Segmentation fault" at run time.help Please just help to modify this code
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
#include<string.h>
int getMax(int arr[], int n)
{
int mx = arr[0];
int i;
for (i = 1; i < n; i++)
if (arr[i] > mx)
mx = arr[i];
return mx;
}
void countSort(int arr[], int n, int exp,int base)
{
int output[n];
int i;
int count[base];
memset(count, 0, sizeof count);
for (i = 0; i < n; i++)
count[ (arr[i]/exp)%base]++;
for (i = 1; i < base; i++)
count[i] += count[i - 1];
for (i = n - 1; i >= 0; i--)
{
output[count[ (arr[i]/exp)%base ] - 1] = arr[i];
count[ (arr[i]/exp)%base ]--;
}
for (i = 0; i < n; i++)
arr[i] = output[i];
}
void radixsort(int arr[], int n,int base)
{
int m = getMax(arr, n);
int exp;
for (exp = 1; m/exp > 0; exp *= 10)
countSort(arr, n, exp , base);
}
void print(int arr[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("%d ",arr[i]);
}
int main(int argc,int argv[])
{
int base=atoi(argv[1]);
int num,i;
FILE *fp1=fopen("myFile1.txt","r");
int arr[50];
while(fscanf(fp1,"%d",&num)==1)
{
arr[i]=num;
i++;
}
int n = sizeof(arr)/sizeof(arr[0]);
radixsort(arr, n ,base);
print(arr, n);
fclose(fp1);
return 0;
}
You are assuming that the compiler has set the initial value of i to 0. However, this is not guaranteed. While many compilers reset variables to 0, many others just leave the contents of memory set at whatever it happened to be at compile time or at load time. You need to initialize the value before using it.
Additionally, you do not test to ensure that you are not overrunning the arr buffer. For example consider what would happen to arr[] if you happen to open a file that has 51 entries. You would attempt to add an entry to arr[50] which overruns the buffer.
You need to initialize i to 0 and make sure to break out if i becomes too great.
The calculation of n is always 50 because arr is 50 ints. You should use i as the count of how many entries have been read in.
int main(int argc,int argv[])
{
int base=atoi(argv[1]);
// int num,i; // This is the line that causes the error
int num;
int i = 0; // This needs to be initialized before use.
FILE *fp1=fopen("myFile1.txt","r");
int arr[50];
// You need to ensure that i does not overrrun the buffer.
while(fscanf(fp1,"%d",&num)==1 && (i < 49))
{
arr[i]=num;
i++;
}
// Since i was defined before the while, it should have the correct count
// This calculation of n is wrong if fewer than a full buffer is read
int n = sizeof(arr)/sizeof(arr[0]);
radixsort(arr, n, base);
print(arr, n);
fclose(fp1);
return 0;
}