Right now I am programming a thing that takes clues to mastermind and return how many guesses should be left to get the secret code correct. I have a small problem however, as it only works on the last guess that is input, so if only one guess is input, it is correct, but any more and it is not...
Here is my code right now:
#include <stdio.h>
#include <stdlib.h>
int bPegs(int *secret, int *sarr);
void frequency(int *array, int *freq);
int tPegs(int *freqA, int *freqG);
void perm(int list[],int k, int n);
int check(int ba, int bb, int wa, int wb);
int slots, colors, guesses;
int *guess;
int counter = 0;
int main() {
int runs, k;
scanf("%d", &runs);
for (k = 0; k < runs; k++) {
int i, j;
scanf("%d", &slots);
scanf("%d", &colors);
scanf("%d", &guesses);
guess = malloc(sizeof(int) * slots + 2);
int *list = malloc(sizeof(int) * slots);
for (i = 0; i < guesses; i++) {
for (j = 0; j < slots + 2; j++) {
scanf("%d", &guess[j]);
}
}
perm(list, 0, slots);
printf("%d", counter);
}
return 0;
}
int bPegs(int *secrets, int *sarr) {
int i;
int black = 0;
for (i = 0; i < slots; i++) {
if (secrets[i] == sarr[i]) {
black++;
}
}
return black;
}
void frequency(int *array, int *freq) {
int i;
for (i = 0; i < slots; i++) {
freq[array[i]]++;
}
}
int tPegs(int *freqA, int *freqG) {
int i, total = 0;
for (i = 0; i < colors; i++) {
if (freqG[i] > freqA[i]) {
total += freqA[i];
}
if (freqG[i] < freqA[i] && freqG[i] != 0) {
total += freqG[i];
}
if (freqG[i] == freqA[i] && freqA[i] != 0) {
total+=freqG[i];
}
}
return total;
}
int check(int ba,int bb, int wa, int wb) {
if (ba == bb && wa == wb) {
return 1;
} else {
return 0;
}
}
void perm(int list[], int k, int n) {
int j;
int *freqA = calloc(colors, sizeof(int));
int *freqG = calloc(colors, sizeof(int));
if (k == n) {
frequency(list, freqA);
frequency(guess, freqG);
int ba = bPegs(list, guess);
int ta = tPegs(freqA, freqG);
int wa = ta - ba;
int bb = guess[slots];
int wb = guess[slots + 1];
if (check(ba, bb, wa, wb)) {
counter++;
}
} else {
int i;
for (i = 0; i < colors; i++) {
list[k] = i;
perm(list, k + 1, n);
}
}
}
Here is some sample input / output:
input:
1
10 2 1
1 0 1 0 1 0 1 0 1 5 4
output:
200
this much is correct, for an example of it breaking:
input:
1
4 6 4
0 1 2 3 0 2
2 2 4 1 0 2
4 3 3 2 1 1
1 3 5 4 1 3
should give:
1
but it does give:
8
and I cannot figure out how to set this up for more than just one clue... any help would be great.
The main reading loop seems incorrect:
for (j = 0; j < slots + 2; j++) {
("%d", &guess[j]);
}
Did you mean this instead:
for (j = 0; j < slots + 2; j++) {
scanf("%d", &guess[j]);
}
Related
I'm trying to write an iterative function that computes all the permutations of an array of numbers given in input.
Here is the code I've written so far.
void permute(int *a, int size){
int j=0, i, h=0, m;
bool flag=true;
int f = factorial(size);
int *arr, *res;
int counter=0;
arr = malloc(f*sizeof(int));
for(i=0; i<f; i++)
arr[i] = 0;
while (j < f) {
if(arr[j]<j)
{
if(j%2 == 0)
{
swap(a[0],a[j]);
} else {
swap(a[arr[j]], a[j]);
}
arr[j]++;
j=0;
} else{
arr[j] = 0;
j++;
}
printf("%d\n",a[j] );
}
}
The code doesn't compute well all the permutations and goes into a long loop. Can someone help me, please? Thanks to everyone.
Your code is close but includes some problems. For instance, the while loop
while (j < f) will assign j to a value out of bound of the array a.
Instead would you please try:
#include <stdio.h>
#include <stdlib.h>
int factorial(int x)
{
int i;
int y = 1;
for (i = 1; i <= x; i++) {
y *= i;
}
return y;
}
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(int *a, int size)
{
int i, j = 0;
int f = factorial(size);
int *arr;
arr = calloc(f, sizeof(int)); // the members are initialized to 0
// print the original array
for (i = 0; i < size; i++) {
printf("%d%s", a[i], i == size - 1 ? "\n" : " ");
}
while (j < size) {
if (arr[j] < j) {
if (j % 2 == 0) {
swap(a + 0, a + j);
} else {
swap(a + arr[j], a + j);
}
// print the rearranged array
for (i = 0; i < size; i++) {
printf("%d%s", a[i], i == size - 1 ? "\n" : " ");
}
arr[j]++;
j = 0;
} else {
arr[j] = 0;
j++;
}
}
free(arr);
}
int main()
{
int a[] = {1, 2, 3}; // example
permute(a, sizeof a / sizeof a[0]); // the 2nd argument is the array length
return 0;
}
Output of the example:
1 2 3
2 1 3
3 1 2
1 3 2
2 3 1
3 2 1
This below is my ds hw code.
#include <stdio.h>
typedef struct
{
int row;
int col;
int val;
}term;
void CreateTriplet(term t[],int a[][10],int m, int n)
{
int i, j, k = 0;
t[0].row = m;
t[0].col = n;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j ++)
{
if(a[i][j] == 0)
continue;
k++;
t[k].row = i;
t[k].col = j;
t[k].val = a[i][j];
}
}
t[0].val = k;
}
void printTriplet(term t[], int k)
{
int i;
for(i = 0 ; i < k ; i++)
{
printf("%d\t", t[i].row);
printf("%d\t", t[i].col);
printf("%d\n", t[i].val);
}
}
void findTranspose(term t1[], term t2[])
{
int i, j, k;
t2[0].row = t1[0].col;
t2[0].col = t1[0].row;
t2[0].val = t1[0].val;
k = 1;
for (i = 0; i < t1[0].col; i++)
{
for (j = 1; j <=t1[0].val; j++)
{
if (t1[j].col == i)
{
t2[k].row = t1[j].col;
t2[k].col = t1[j].row;
t2[k].val = t1[j].val;
k++;
}
}
}
}
int main()
{
int a[10][10], i, j, m, n, zero=0, nonzero;
term t1[101], t2[102];
scanf("%d %d", &m, &n);
for(i = 0; i < m ;i++)
{
for(j= 0; j < n ;j++)
{
scanf("%d]\n", &a[i][j]);
if(a[i][j]==0)
zero++;
}
}
if (i*j != i*i && j*j) /* I have no idea how to modify this section for the output*/
{
printf("Input matrix has wrong size. Please input again. \n");
}
else
{
nonzero = m * n - zero;
printf("Sparse matrix by triplet form:\n");
CreateTriplet(t1, a, m, n);
printTriplet(t1, nonzero+1);
findTranspose(t1, t2);
printf("Transpose of the sparse matrix:\n");
printTriplet(t2, nonzero+1);
}
return 0;
}
The main problem is in the section (if statement.)
When I was writing the if conditional, the input size was 6 * 6. Also, the elements in the matrix are not 6 * 6. My idea is to let the condition determine row * col != input elements. I don't know how to modify the if statement. Can someone help me?
**Input**
55
15 0 0 22 0
0 0 3 0 0
0 0 0 -6 0
0 0 0 0 7
91 0 0 0 0
**Output**
Sparse matrix by triplet form:
5 5 6
0 0 15
0 3 22
1 2 3
2 3 -6
3 4 7
4 0 91
Transpose of the sparse matrix:
5 5 6
0 0 15
0 4 91
2 1 3
3 0 22
3 2 -6
4 3 7
**Input**
66
15 0 0 22 0 -15 100
0 11 3 0 0 0
0 0 0 -6 0 0
0 0 0 0 0 0
91 0 0 0 0 0
0 0 28 0 0 0
1 0 0 0 0 0
**Output**
Input matrix has wrong size. Please input again.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int row;
int col;
int val;
} term;
void CreateTriplet (term t[],int a[][10],int m, int n) {
int i, j, k = 0;
t[0].row = m;
t[0].col = n;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j ++) {
if(a[i][j] == 0)
continue;
k++;
t[k].row = i;
t[k].col = j;
t[k].val = a[i][j];
}
}
t[0].val = k;
}
void printTriplet(term t[], int k) {
int i;
for(i = 0 ; i < k ; i++) {
printf("%d\t", t[i].row);
printf("%d\t", t[i].col);
printf("%d\n", t[i].val);
}
}
void findTranspose(term t1[], term t2[]) {
int i, j, k;
t2[0].row = t1[0].col;
t2[0].col = t1[0].row;
t2[0].val = t1[0].val;
k = 1;
for (i = 0; i < t1[0].col; i++) {
for (j = 1; j <=t1[0].val; j++) {
if (t1[j].col == i) {
t2[k].row = t1[j].col;
t2[k].col = t1[j].row;
t2[k].val = t1[j].val;
k++;
}
}
}
}
int main (int argc, char * *argv, char * *envp) {
int a[10][10], i, j, m, n, zero = 0, nonzero;
term t1[101], t2[102];
int ok_or_not = 1;
while (ok_or_not == 1) {
scanf ("%d %d", &m, &n);
if (m * n != m * m) {
printf ("Input matrix has wrong size. Please input again. \n");
}
else {
ok_or_not = 0;
}
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
scanf("%d]\n", &a[i][j]);
if (a[i][j] == 0)
zero++;
}
}
if (i * j != i * i && j * j) { /* I have no idea how to modify this section for the output*/
} else {
nonzero = m * n - zero;
printf("Sparse matrix by triplet form:\n");
CreateTriplet(t1, a, m, n);
printTriplet(t1, nonzero + 1);
findTranspose(t1, t2);
printf("Transpose of the sparse matrix:\n");
printTriplet(t2, nonzero + 1);
}
return (EXIT_SUCCESS);
}
Hi I need help please i need to fix this code so it count the value only once
for exmaple
input:
25
38 25 36 4 1 1 10 37 45 21 37 42 21 1 50 9 50 42 6 39 10 14 17 11 20
10
36 42 2 15 28 42 3 23 8 50
output:
4
the answer here should be 4 not 7.
#include <stdio.h>
int main()
{
int n, m, count = 0;
int array[1000];
int subarray[1000];
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &array[i]);
}
scanf("%d", &m);
for (int i = 0; i < m; i++)
{
scanf("%d", &subarray[i]);
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if (array[i] == subarray[j])
count++;
}
}
printf("%d\n", count);
}
Possible solution, using functions and qsort.
(untested code)
#include <stdio.h>
int binarySearch(int arr[], int l, int r, int x) {
if (r >= l) {
int mid = l + (r - l) / 2;
if (arr[mid] == x)
return mid;
if (arr[mid] > x)
return binarySearch(arr, l, mid - 1, x);
return binarySearch(arr, mid + 1, r, x);
}
return -1;
}
int cmpfunc (const void * a, const void * b) {
return (*(int*)a > *(int*)b) - (*(int*)a < *(int*)b);
}
int main() {
int n, m, count = 0;
int array[1000];
int subarray[1000];
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &array[i]);
}
qsort(array, n, sizeof(int), cmpfunc); // O(n lg n)
scanf("%d", &m);
for (int i = 0; i < m; i++) {
scanf("%d", &subarray[i]);
int result = binarySearch(arr, 0, n - 1, x); // O(lg n)
if (result != -1)
count++;
} // O(m lg n)
printf("%d\n", count);
}
You need to keep track of the matched values in third array as following and
check if the new value is found before or not
#include <stdio.h>
int main()
{
int n, m, count = 0;
int array[1000];
int subarray[1000];
int result[1000];
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &array[i]);
}
scanf("%d", &m);
for (int i = 0; i < m; i++)
{
scanf("%d", &subarray[i]);
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if (array[i] == subarray[j]){
int isFound=0;
for(int k=0;k<count;k++){
if(result[k]==array[i])
isFound=1;
}
if(isFound==0){
result[count]==array[i];
count++;
}
}
}
}
printf("%d\n", count);
}
I use a boolean variable to check if the elements of array 1 exist in the array 2 ,if not ,i will copied it to array 3
#include <stdio.h>
#include <stdbool.h>//header how found the booleen variable
int main()
{
int n,m;
do
{
printf("Give me the length of array 1 :");
scanf("%d",&n);
}while(n<1);
int T1[n];//declaration of Array 1
do
{
printf("Give me the length of array 2 :");
scanf("%d",&m);
}while(m<1);
int T2[m];//declaration of Array 2
printf("The fill of Array 1:\n\n");
for(int i=0;i<n;i++)
{
scanf("%d",&T1[i]);
}
printf("The fill of Array 2:\n\n");
for(int j=0;j<m;j++)
{
scanf("%d",&T2[j]);
}
int T3[n+m];//declaration of Array 3
bool found=false;//declaration of booleen variable
int k=0;
for(int i=0;i<n;i++)
{found=false;
for(int j=0;j<m;j++)
{
if(T1[i]==T2[j])
{
found=true;
}
}
if(found==true)
{
T3[k]=T1[i];
k++;
}
}
printf("\nThe number of elment duplicate is :%d\n",k);
}
so it count the value only once
With minimal impact to OP's code and without re-ordering input:
Check if the subarray[] value already occurred within itself.
When subarray[]/array[] values match, quit looking.
for (int j = 0; j < m; j++) {
bool unique_subarray_value = true;
for (int earlier = 0; earlier < j; earlier++) {
if (subarray[earlier] == subarray[j])
unique_subarray_value = false;
break;
}
}
if (unique_subarray_value) {
for (int i = 0; i < n; i++) {
if (array[i] == subarray[j]) {
count++;
break;
}
}
}
}
A fast approach would sort the arrays and then walk them
// Pseudo code
sort array[n] with qsort()
sort subarray[m] with qsort()
// walk the arrays looking for matches
i = 0;
j = 0;
while (i < n && j < m) {
if (array[i] == subarray[j]) {
count++;
while (i + 1 < n && array[i] == array[i+1]) i++;
while (j + 1 < m && subarray[j] == subarray[j+1]) j++;
}
if (array[i] < subarray[j]) i++;
else j++;
}
I wrote a program that:
gets integers to arr1[3] by user's input
get another input - called max number.
arr2[3] gets random 3 numbers ranging from 0 to maxNumber.
for e.g. if I enter number 4, then arr2[] will contain 3 integers from 0 to 3 (included).
4.Build arr3[3] which contains arr1[3] integers that ARE NOT in arr2[3] for e.g. if arr1[3] = 1 2 3, arr2[3] = 2 5 6, then arr3[3] = 1 3 garbage here
Print arr3[].
Weird problem: It prints only arr3[0] which is arr1[2]'s value, for some reason. Any suggestions?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define N 3
void inputArr1(int arr1[]);
void maxValueC(int maxValue);
void inputArr2(int arr2[], int maxValue);
void inputArr3(int arr1[], int arr3[], int i, int count3);
void printArr3(int arr1[], int arr3[]);
void main()
{
int i = 0, j = 0, count = 0, count3 = 0, maxValue = 0, arr1[N], arr2[N], arr3[N];
inputArr1(arr1);
printf("please enter maxValue: ");
scanf("%d", &maxValue);
while (maxValue <= 0)
{
maxValueC(maxValue);
}
srand(time(NULL));
inputArr2(arr2, maxValue);
printf("\nArray1: ");
for (i = 0; i < N; i++)
{
printf("%d ", arr1[i]);
}
printf("\nArray2: ");
for (i = 0; i < N; i++)
{
printf("%d ", arr2[i]);
}
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (arr1[i] != arr2[j])
{
count++;
}
}
if (count == N)
{
inputArr3(arr1, arr3, i, count3);
}
count = 0;
}
printArr3(arr1, arr3);
getch();
}
void inputArr1(int arr1[])
{
int i;
for (i = 0;i < N;i++)
{
printf("Please enter a digit[%d]: ",i);
scanf("%d", &arr1[i]);
printf("\n");
}
}
void maxValueC(int maxValue)
{
printf("Please enter a number that is bigger than 0!!!");
scanf("%d", &maxValue);
}
void inputArr2(int arr2[], int maxValue)
{
int i;
for (i = 0; i < N; i++)
{
arr2[i] = rand() % (maxValue);
}
}
void inputArr3(int arr1[], int arr3[], int i, int count3)
{
arr3[count3] = arr1[i];
count3++;
}
void printArr3(int arr3[])
{
int i;
printf("\nArray3: ");
for (i = 0; i < N; i++)
{
printf("%d", arr3[i]);
}
}
When you call inputArr3() you pass count3 as argument by value (it goes to your stack) and later you manipulate the value (in the stack) but your count3 variable (defined in main) will never be altered.
You probably want to pass pointer to count3, for example:
void inputArr3(int arr1[], int arr3[], int i, int *count3)
{
...
(*count3)++;
}
When you call the function you have to change it to as follows:
inputArr3(arr1, arr3, i, &count3);
Another problem is when you call printArr3 - you call it with 2 arguments while it takes one. I suggest you change the call to printArr3 as follows:
printArr3(arr3);
Do not forget to modify your function prototypes.
I hope this is what you need, because is hard to understand:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define N 3
int main(void){
int arr1[N];
int arr2[N];
int arr3[N];
int found = 0;
int a,b,i,j,k=0,t=0;
int maxNumber = 8;
srand((unsigned)time(NULL));
/* create Arr1 */
for (a = 0; a < N; a++){
arr1[a] = (rand() % maxNumber);
}
/* create Arr2 */
for (a = 0; a < N; a++){
arr2[a] = (rand() % maxNumber);
}
/* Print Arr1 */
printf("Arr1\n");
for (b = 0; b < N; b++){
printf("%d ",arr1[b]);
}
/* Print Arr2 */
printf("\nArr2\n");
for (b = 0; b < N; b++){
printf("%d ",arr2[b]);
}
/* create Arr3 */
for(i=0;i<N;i++){
for(j=0;j<N;j++){
if(arr1[t] == arr2[j]){
found++;
}
}
if(!found){
arr3[k]=arr1[t];
k++;
}
found=0;
t++;
}
/* Print Arr3 */
printf("\nArr3\n");
for(int u=0;u<k;u++){
printf("%d ",arr3[u]);
}
printf("\n");
return 0;
}
Output1:
Arr1
0 4 2
Arr2
6 1 2
Arr3
0 4
Output2:
Arr1
6 0 1
Arr2
0 7 5
Arr3
6 1
Output3:
Arr1
7 2 7
Arr2
7 5 6
Arr3
2
This program is supposed to sort numbers entered from the command line as -a for small to large sort, or -d for large to small sort. I compiled this program earlier, ran it and the output was fine. I tested it on my laptop later and then the sorting was all wasn't working correctly.
I entered ./sort -a 5 14 10 18 20 2 100 6 7 1 The Result: -1950355064 2 5 6 10 14 18 20 100 I entered: ./sort -d 5 14 10 18 20 2 100 6 7 1 The Result: 761262572 32767 18 14 10 6 20 5 100 2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
// function declarations
void small_to_large(int a[], int n);
void large_to_small(int a[], int n);
int main(int argc, char *argv[])
{
int i;
char letter_d[3] = "-d"; // find "-d" in function
char letter_a[3] = "-a"; // find "-a" in function
int arg_d;
int arg_a;
char *find_letter = argv[1];
int stringToInt[N+1];
for( i = 0; i < argc; i++){
printf("%s ", argv[i]);
}
printf("\n");
arg_d = strcmp(find_letter, letter_d);
arg_a = strcmp(find_letter, letter_a);
if (arg_d == 0) {
printf("descend!\n");
for(i = 2; i<argc; i++) {
stringToInt[i] = atoi(argv[i]);
}
large_to_small(stringToInt, N);
for(i = 0; i < N; i++) {
printf(" %d", stringToInt[i]);
}
}
else if (arg_a == 0) {
printf("ascend!\n");
for(i = 2; i < argc; i++) {
stringToInt[i] = atoi(argv[i]);
}
small_to_large(stringToInt, N);
for(i = 0; i < N; i++) {
printf(" %d", stringToInt[i]);
}
}
else {
printf("Invalid command: %s\n", find_letter);
}
printf("\n");
return 0;
}
// small_to_large function
void small_to_large(int a[], int n)
{
int i, largest = 0, temp;
if (n == 1)
return;
for (i = 1; i < n; i++)
if (a[i] > a[largest])
largest = i;
if (largest < n - 1) {
temp = a[n-1];
a[n-1] = a[largest];
a[largest] = temp;
}
small_to_large(a, n - 1);
}
// large_to_small function
void large_to_small(int a[], int n)
{
int i, largest = 0, temp;
if(n == 1)
return;
for (i = n; i >= 2; i--)
if(a[i] < a[largest])
largest = i;
if (largest < n - 1) {
temp = a[n-1];
a[n-1] = a[largest];
a[largest] = temp;
}
large_to_small(a, n-1);
}
There are mainly two problems.
stringToInt[i] = atoi(argv[i]); : index of stringToInt should
start from 0.
large_to_small is wrong. Sorting algorithm may be the same. So you can use the same code.
Fix to sample:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// function declarations
void small_to_large(int a[], int n);
void large_to_small(int a[], int n);
#define OPT_D "-d"
#define OPT_A "-a"
int main(int argc, char *argv[]) {
int i;
for(i = 0; i < argc; i++){
printf("%s ", argv[i]);
}
printf("\n");
int n = argc - 2;//-2 : program_name and option
if(n <= 0){
printf("Usage : %s option(-a or -d) numbers...\n", *argv);
return EXIT_FAILURE;
}
int stringToInt[n];
for(i = 0; i < n; ++i)
stringToInt[i] = atoi(argv[i+2]);
char *opt = argv[1];
bool opt_d, opt_a;
opt_d = !strcmp(opt, OPT_D);
opt_a = !strcmp(opt, OPT_A);
if(opt_d){
printf("descend!\n");
large_to_small(stringToInt, n);
} else if(opt_a) {
printf("ascend!\n");
small_to_large(stringToInt, n);
} else {
printf("Invalid option: %s\n", opt);
return EXIT_FAILURE;
}
for(i = 0; i < n; i++) {
printf("%d ", stringToInt[i]);
}
printf("\n");
return 0;
}
void selection_sort(int a[], int n, bool test(int a, int b)){
int i, select = 0, temp;
if (n == 1)
return;
for (i = 1; i < n; i++)
if(test(a[i], a[select]))
select = i;
if (select != n-1) {
temp = a[n-1];
a[n-1] = a[select];
a[select] = temp;
}
selection_sort(a, n - 1, test);
}
static inline bool greater(int a, int b){
return a > b;
}
static inline bool smaller(int a, int b){
return a < b;
}
// small_to_large function
void small_to_large(int a[], int n) {
selection_sort(a, n, greater);
}
// large_to_small function
void large_to_small(int a[], int n){
selection_sort(a, n, smaller);
}
I believe I managed to get it to work by changing
large_to_small(stringToInt, N); ---> large_to_small(stringToInt, argc);
small_to_large(stringToInt, N); ---> small_to_large(stringToInt, argc);