Sudoku multiple solutions C - c

Here is my C sudoku solver using recursive backtracing, with help code from online. The program is small, and branches of the puzzle are stored on the stack and it moves forward adding new puzzle's, and if it fails to find a solution for a position it returns to the previous branch and continues.
While this works for finding 1 solution, I'm trying to adapt it to print every solution. Where the else clause /* SOLUTION FOUND AS NO MORE EMPTY BLOCKS! */ is what ends the function, I've tried returning as sudokuSolver() with various (rows,cols) but can't seem to get to continue correctly to print all solutions.
Code:
#include <stdio.h>
#include <string.h>
int isAvailable(int puzzle[][9], int row, int col, int num)
{
int rowStart = (row/3) * 3;
int colStart = (col/3) * 3;
int i, j;
for(i=0; i<9; ++i) {
if (puzzle[row][i] == num)
return 0;
if (puzzle[i][col] == num)
return 0;
if (puzzle[rowStart + (i%3)][colStart + (i/3)] == num)
return 0;
}
return 1;
}
int solveSudoku(int puzzle[][9], int row, int col)
{
int i;
if (row<9 && col<9) {
if(puzzle[row][col] != 0) {
if ((col+1) < 9)
return solveSudoku(puzzle, row, col+1);
else if ((row+1) < 9)
return solveSudoku(puzzle, row+1, 0);
else /*SOLUTION FOUND AS NO MORE EMPTY BLOCKS!*/
return 1;
}
else {
for(i=0; i<9; ++i) {
if(isAvailable(puzzle, row, col, i+1)) {
puzzle[row][col] = i+1;
if ((col+1) < 9){
if (solveSudoku(puzzle, row, col +1))
return 1;
else
puzzle[row][col] = 0;
}
else if ((row+1) < 9) {
if (solveSudoku(puzzle, row+1, 0))
return 1;
else
puzzle[row][col] = 0;
}
else
return 1;
}
}
}
return 0;
}
else {
return 1;
}
}
int main()
{
int sudoku_arr[9][9] = {
{8,0,0,6,0,0,9,0,5},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,2,0,3,1,0},
{0,0,7,3,1,8,0,6,0},
{2,4,0,0,0,0,0,7,3},
{0,0,0,0,0,0,0,0,0},
{0,0,2,7,9,0,1,0,0},
{5,0,0,0,8,0,0,3,6},
{0,0,3,0,0,0,0,0,0}
};
if (solveSudoku(sudoku_arr, 0, 0)) { //Solve sudoku puzzle
printf("\nSudoku solved:\n");
int row, col;
for(row=0; row<9; row++) {
for(col=0; col<9; col++) {
printf("%d ", sudoku_arr[row][col]);
}
printf("\n");
}
return 0;
}
else {
printf("\nNo sudoku solution");
return -1;
}
}
Now while this solves with the first solution:
Sudoku solved:
8 1 4 6 3 7 9 2 5
3 2 5 1 4 9 6 8 7
7 9 6 8 2 5 3 1 4
9 5 7 3 1 8 4 6 2
2 4 1 9 5 6 8 7 3
6 3 8 2 7 4 5 9 1
4 6 2 7 9 3 1 5 8
5 7 9 4 8 1 2 3 6
1 8 3 5 6 2 7 4 9
There are many other possible solutions i.e.
814637925325149687796825314957318462241956873638274591462793158579481236183562749
814637925325941687796825314957318462241569873638472591462793158579184236183256749
834671925125839647796425318957318462241956873368247591682793154579184236413562789
834671925125839647796524318957318462241956873368247591682793154519482736473165289
834671925125839647796524318957318462241965873368247591682793154519482736473156289

The sudoku_arr is passed by reference. When you set a value inside solveSudoku () function, you are overwriting the original array and hence when it tries to backtrack, there are no more locations with 0 value on array.
What you really want to do is to reset the value to 0 in solveSudoku () before you return 1;.
Also, you would want to print the solution as soon as there are no empty locations left before returning.
This might be helpful.

Related

How to count sequence of numbers in array

I want to count sequence of numbers together, by always adding the next number to the sum of numbers before. Then do it all again but start one number up. Like this. Then find duplicated sums.
1 5 2 4 2 2 2(sequence)
0..1: 1 5 sum=6
0..2: 1 5 2 sum=8
0..3: 1 5 2 4 sum=12
0..4: 1 5 2 4 2 sum=14
0..5: 1 5 2 4 2 2 sum=16
0..6: 1 5 2 4 2 2 2 sum=18
1..2: 5 2 sum=7
1..3: 5 2 4 sum=11
1..4: 5 2 4 2 sum=13
1..5: 5 2 4 2 2 sum=15
1..6: 5 2 4 2 2 2 sum=17
2..3: 2 4 sum=6
2..4: 2 4 2 sum=8
2..5: 2 4 2 2 sum=10
2..6: 2 4 2 2 2 sum=12
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int count = 0;
char temp;
int sekvence[10000];
int countedsequence[10000];
int duplication = 0;
//save user input
do
{
scanf("%d%c", &sekvence[count], &temp);
count++;
} while (temp != '\n');
sekvence[count];
//somehow count it and save to countedsequence
countedsequence[0] = sekvence[0];
countedsequence[0] = countedsequence[0] + sekvence[0 + 1];
for (int i = 1; i < count - 1; i++)
{
countedsequence[i] = countedsequence[i - 1] + sekvence[i + 1];
}
//find duplicated numbers in countedsequence
for (int i = 0; i < count - 1; i++)
{
for (int j = i + 1; j < count - 1; j++)
{
if (countedsequence[i] == countedsequence[j])
{
duplication++;
break;
}
}
}
//idk some printing for testing
for (int i = 0; i < count - 1; i++)
{
printf("%d ", countedsequence[i]);
}
printf("%d\n", duplication);
return 0;
}
I only managed to count from start to end how do I start counting again with one up to the end?
I usually revise op's code into an solution but the use of non-English variable mean that require unnecessary extra effort. The only working functionality is the interactive input handling but that gets in way during development.
To generate each range of the sequence using two loops (for start and end) and at third to generate the sum of said range (sequence_sum()).
With an unordered array of numbers we can find duplicates by a tweaked partition algorithm that that swap elements into 3 sections: one instance of each duplicates [0; i[, todo [i; sum_len - i[ and processed [ sum_len; [. This is an O(n^2) algorithm. A more efficient O(n) solution would use a hash map from sum to count at the cost of additional code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
size_t duplicate_sum(size_t sum_len, const int sum[sum_len], int duplicate[sum_len]) {
size_t i = 0;
memcpy(duplicate, sum, sum_len * sizeof(*sum));
for(; i < sum_len;) {
int found = 0;
for(size_t j = i + 1; j < sum_len; j++) {
if(duplicate[i] == duplicate[j]) {
found = 1;
swap(duplicate + j, duplicate + sum_len - 1);
sum_len--;
}
}
if(found) {
i++;
} else {
swap(duplicate + i, duplicate + sum_len - 1);
sum_len--;
}
}
return i;
}
void sequence_sum(size_t len, const int sequence[len], int sum[len * (len - 1) / 2]) {
for(size_t i = 0, s = 0; i < len - 1; i++) {
for(size_t j = i + 1; j < len; j++, s++) {
sum[s] = 0;
printf("%zu..%zu: ", i, j);
for(size_t k = i; k <= j; k++) {
printf(" %d", sequence[k]);
sum[s] += sequence[k];
}
printf("%*.0ssum=%d\n", (int) (2 * len - 2 * (j - i)), "", sum[s]);
}
}
}
int main(void) {
int sequence[] = { 1,5,2,4,2,2,2 };
size_t sequence_len = sizeof sequence / sizeof *sequence;
size_t sum_len = sequence_len * (sequence_len - 1) / 2;
int sum[sum_len];
sequence_sum(sequence_len, sequence, sum);
int duplicate[sum_len];
printf("duplicates: ");
size_t duplicate_len = duplicate_sum(sum_len, sum, duplicate);
for(size_t i = 0; i < duplicate_len; i++) {
printf(" %d", duplicate[i]);
}
printf("\n");
and the output:
0..1: 1 5 sum=6
0..2: 1 5 2 sum=8
0..3: 1 5 2 4 sum=12
0..4: 1 5 2 4 2 sum=14
0..5: 1 5 2 4 2 2 sum=16
0..6: 1 5 2 4 2 2 2 sum=18
1..2: 5 2 sum=7
1..3: 5 2 4 sum=11
1..4: 5 2 4 2 sum=13
1..5: 5 2 4 2 2 sum=15
1..6: 5 2 4 2 2 2 sum=17
2..3: 2 4 sum=6
2..4: 2 4 2 sum=8
2..5: 2 4 2 2 sum=10
2..6: 2 4 2 2 2 sum=12
3..4: 4 2 sum=6
3..5: 4 2 2 sum=8
3..6: 4 2 2 2 sum=10
4..5: 2 2 sum=4
4..6: 2 2 2 sum=6
5..6: 2 2 sum=4
duplicates: 6 8 12 10 4

Making an empy Sudoku solver on C

So i got an assignment in class to make an empty sudoku that every time creates a random solution of 9x9.
I got to the point where i get different number each row and column but not on every 3x3 matrix and i cannot figure out how to go on from here.
We didnt learn recursion yet and can use only the libraries listed in the code.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NINE 9
#define ONE 1
void solve_sudoku(int board[9][9])
{
srand(time(0));
int count = 0;
for (int i = 0;i <= NINE;i++)
{
for (int j = 0;j < NINE;j++)
{
board[i][j] =(rand() % NINE)+ONE;
for (int k = 0;k < 9;k++)
{
int clone_i = i;
int clone_j = j;
while (board[i][k] == board[i][j])
{
if (j == k)
{
break;
}
count++;
board[i][j] = (rand() % NINE) + ONE;
k = 0;
}
while(board[k][j]==board[i][j])
{
if (i == k)
{
break;
}
count++;
board[i][j] = (rand() % NINE) + ONE;
k = 0;
}
if (count > 300 || (board[i][j] == board[i][k] && j != k))
{
for (int i = clone_i;i < clone_i + 1;i++)
for (int l = 0;l < 9;l++)
{
board[i][l] = 0;
}
count = 0;
k = 0;
j = 0;
}
}
}
}
}
void print_sudoku(int board[][9])
{
printf("The soduko solution is: \n");
for (int i = 0;i < NINE;i++)
{
for (int k = 0;k < NINE;k++)
{
printf("%d ", board[i][k]);
}
printf("\n");
}
}
int main()
{
int sud[9][9] = { 0 };
int matrix_size = 9;
solve_sudoku(sud);
print_sudoku(sud);
return 0;
}
I take you to mean that you need to generate random 9 x 9 grids of digits that meet the Sudoku criterion that each row, column and block contains all nine digits. In that case, you are going about it a very difficult way. Perhaps that was inspired by viewing the program as a solver, instead of what it really needs to be: a generator.
Consider that it is easy to write down at least one valid Sudoku algorithmically:
1 2 3 | 4 5 6 | 7 8 9
4 5 6 | 7 8 9 | 1 2 3
7 8 9 | 1 2 3 | 4 5 6
------+-------+------
2 3 4 | 5 6 7 | 8 9 1
5 6 7 | 8 9 1 | 2 3 4
8 9 1 | 2 3 4 | 5 6 7
------+-------+------
3 4 5 | 6 7 8 | 9 1 2
6 7 8 | 9 1 2 | 3 4 5
9 1 2 | 3 4 5 | 6 7 8
Now consider that you can always transform one valid Sudoku into a different one by swapping two rows or two columns such that no entries move from one block to another. For example, you can swap the first row with the third, or the fifth column with the sixth. If you perform a bunch of random swaps of that kind on a valid starting Sudoku then you will end up with a random grid that meets the Sudoku criteria.
Note that it is a different story if you need to produce only Sudoku that can be solved by deduction alone, without trial & error. For that you probably do need a solver-based approach, but that starts with a bona fide solver, and nothing in your code is anything like that.

Check whether a given Matrix(m*n) has any matrix inside of it that can be transposed

I need to check if I can find inside of given matrix size of 5*8
a matrix that has a transpose and if there is more than one I must find the biggest one.
example of a given matrix
1 2 0 3 2 1 0 7
2 3 4 1 2 3 4 5
3 4 6 2 5 6 7 6
4 5 7 3 6 8 9 8
6 7 1 4 7 9 0 9
in this matrix we can find a matrix 4x4
that has transpose and its the biggest matrix in the main matrix
1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 0
#include <stdio.h>
#define M 4
#define column 5
#define row 8
int main()
{
int matrixA[5][8];
printf("please enter a matrix to check if there is a transpose matrix\n");
for (int i = 0; i < column; i++)
{
for (int j = 0; j < row; j++)
{
printf("please enter %d row and %d column: ", i + 1, j + 1);
scanf("%d", &matrixA[i][j]);
}
}
transpose(matrixA, column, row);
}
void transpose(int A[][row], int c, int r)
{
int matrixAT[M][M];
for (int size = r; size > 0; size--)
{
for (int j = 0; j < c - size + 1; j++)
{
for (int b = 0; b <= r - size; b++)
{
printf("Checking Matrix at row: %d , column: %d ,size: %dx%d", j, b, size, size);
for (int k = j, w = 0; k < size + j; k++, w++)
{
for (int l = b, z = 0; l < size + b; l++, z++)
{
matrixAT[w][z] = A[k][l];
}
printf("/n");
}
if (IsSymmetric(matrixAT, size))
printf("Matrix found");
}
}
}
}
int IsSymmetric(int mat[M][M], int size)
{
int flag = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (mat[i][j] == mat[j][i]) flag++;
}
}
return flag == size * size ? 1 : 0;
}
this is my code i dont know what im doing wrong
Your IsSymmetric is slow as it always check all elements why not stop on first inequality instead? Also copying it to temp array again and again ...
The main problem is You are not checking every position and size as you call transpose(matrixA, column, row); only once outside the loops ...
Also your main does not return anything and its declared as int ...
I would start with brute force like this:
#define column 5
#define row 8
int IsSymmetric(int mat[column][row], int i0,int j0,int size) // check n*n sub matrix at i0,j0 no need to copy again and again to temp array
{
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
if (mat[i0+i][j0+j] != mat[i0+j][j0+i]) return 0;
return 1;
}
int min(int a,int b){ return (a<b)?a:b; } // not sure if min is present in your environment if is comment this line out
int main()
{
int matrixA[5][8];
...
for (int i = 0; i < column; i++)
for (int j = 0; j < row; j++)
for (int n = 1; n <= min(column-i,row-j); n++)
if (IsSymmetric(matrixA,i,j,n))
{
// here do what you want with the i,j,n*n sub matrix
// like remember position and size for the biggest n
}
...
return 0; // return value as you declared int main
}
Hope I did not make any typo in here as I just wrote this into answer editor from your original code.
How ever as you can see its O(n^4) complexity (on average O(n^3)) which is really slow. However for your small matrix its not a problem.
In case you need something faster then we need to know more about the data ... for example what is the range of the values? Some hints:
on positive IsSymmetric test one cell bigger submatrix without testing the previous elements again (recursively increasing diagonal).
use histogram to detect values that might be only on diagonals (appear once globally or odd times locally)
Using the incremental symmetry test results in O(n^3) solution:
//---------------------------------------------------------------------------
#define column 5
#define row 8
//---------------------------------------------------------------------------
void submatrix_print(int mat[column][row], int i0,int j0,int n,int m)
{
int i,j;
printf("%i*%i at %i,%i\r\n",n,m,i0,j0);
for (i=0;i<n;i++,printf("\r\n"))
for (j=0;j<m;j++)
printf("%1i ",mat[i0+i][j0+j]);
}
//---------------------------------------------------------------------------
void submatrix_print_transposed(int mat[column][row], int i0,int j0,int n,int m)
{
int i,j;
printf("%i*%i at %i,%i\r\n",n,m,i0,j0);
for (i=0;i<m;i++,printf("\r\n"))
for (j=0;j<n;j++)
printf("%1i ",mat[i0+j][j0+i]);
}
//---------------------------------------------------------------------------
int min(int a,int b){ return (a<b)?a:b; }
int submatrix_symmetric(int mat[column][row], int i0,int j0) // returns biggest symetric submatrix size >=1 found at i0,j0
{
int i,n,N;
N=min(column-i0,row-j0); // max size that still fits into matrix
for (n=2;n<N;n++) // test all sizes above 1
for(i=0;i<n-1;i++) // only test newly added cells to last sub matrix
if (mat[i0+n-1][j0+i]!=mat[i0+i][j0+n-1])
return n-1; // first non match means last tested size i svalid
return n; // no mismatches mean full size is valid
}
//---------------------------------------------------------------------------
int main()
{
int mat[5][8]=
{
1,2,0,3,2,1,0,7,
2,3,4,1,2,3,4,5,
3,4,6,2,5,6,7,6,
4,5,7,3,6,8,9,8,
6,7,1,4,7,9,0,9,
};
submatrix_print(mat,0,0,5,8);
// submatrix_print_transposed(mat,0,0,5,8);
int i,j,n,i0=0,j0=0,n0=0;
for(i=0;i<column;i++)
for(j=0;j<row;j++)
{
n=submatrix_symmetric(mat,i,j);
if (n0<n){ n0=n; i0=i; j0=j; }
}
submatrix_print(mat,i0,j0,n0,n0);
return 0;
}
//-------------------------------------------------------------------------
The result of the code is:
5*8 at 0,0 // input matrix
1 2 0 3 2 1 0 7
2 3 4 1 2 3 4 5
3 4 6 2 5 6 7 6
4 5 7 3 6 8 9 8
6 7 1 4 7 9 0 9
4*4 at 1,3 // biggest symmetric sub matrix found
1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 0
you can make a function that check if the matrix ican be transposed or no
and another function that take evry time a part from the main matrix and you move it everytime and check it with 1st function
example :
1st matrix :m[1][1] starting from zero
1 2
2 3
2 matrix :m[2][2] starting from one
2 0
3 4
then when you finish with 2 demension matrix you go to 3
till the end
i hope you understand me and sorry for my bad english

Why is my program not dividing even numbers by two?

It should scan 10 int numbers and then display them backwards, dividing the even ones by two, but it just displays them without dividing.
es:
10 9 8 7 6 5 4 3 2 1 ==> 1 2 3 2 5 3 7 4 9 5
but mine does:
10 9 8 7 6 5 4 3 2 1 ==> 1 2 3 4 5 6 7 8 9 10
#include <stdio.h>
int main(void)
{
int a[10];
for(int i = 0; i < 10; i++)
scanf("%d", &a[i]);
for (int i = 0; i < 10; i++) {
if (a[i] % 2 == 0 ) {
a[i] = a[i] / 2; i++;
}
else
i++;
}
for(int i = 9; i > -1; i--)
printf("%d\n", a[i]);
return 0;
}
The middle loop incorrectly increments i twice per iteration:
for (int i = 0; i < 10; i++) { // <<== One increment
if (a[i]%2 == 0 ) {
a[i] = a[i]/2; i++; // <<== Another increment - first branch
}
else
i++; // <<== Another increment - second branch
}
In your case, all even numbers happen to be stored at even positions that your loop skips.
Note: A better solution is to drop the middle loop altogether, and do the division at the time of printing.
The body of your second for loop advances i. Since it's also advanced in the loop's clause, it's advanced twice, effectively skipping any other element. Remove those advancements, and you should be OK:
for(int i=0; i<10; i++) {
if (a[i] % 2 == 0) {
a[i] /= 2;
}
}
In your program you incrementing the for loop variable i two times inside the loop and loop also increment the value one time so the values are skipped that is the reason you are getting wrong output.herewith i have attached the corrected program and its output.hope you understand the concept .Thank you
#include <stdio.h>
int main(void)
{
int a[10];
printf("\n Given Values are");
printf("\n-----------------");
for(int i = 0; i < 10; i++)
scanf("%d", &a[i]);
for (int i = 0; i < 10; i++)
{
if (a[i] % 2 == 0 )
{
a[i] = a[i] / 2;
}
}
printf("\n After dividing the even numbers by 2 and print in reverse order");
printf("\n ----------------------------------------------------------------\n");
for(int i = 9; i > 0; i--)
printf("%d\n", a[i]);
return 0;
}
Output
Given Values are
-----------------
1
2
3
4
5
6
7
8
9
10
After dividing the even numbers by 2 and print in reverse order
----------------------------------------------------------------
5
9
4
7
3
5
2
3
1

C Program output differs on different machines

I have the following program -
#include <stdio.h>
int main() {
int counter = 0;
int responses[28];
printf("Enter student section values: \n");
while(counter != 27) {
scanf("%d", &responses[counter]);
counter++;
}
int i = 0;
int arrayBlank[100];
int temp = 0;
int past = 0;
int present = 0;
int future = 0;
int flag = 0;
for(i = 0; i < counter; i++) {
if((i - 1) < 0 || (i + 1 >= counter)) {
;
}
else {
past = responses[i - 1];
present = responses[i];
future = responses[i + 1];
if(present == past || present == future) {
temp = present;
flag=1;
arrayBlank[temp]++;
} else {
arrayBlank[i] = 0;
}
}
}
if(flag == 0) {
printf("\nThe order input does not assign any adjacent students from the same team\n");
return 0;
} else {
int chut[28];
int index = 0;
for(i = 0; i < 27; i++) {
index = responses[i];
chut[index]++;
}
for(i = 0; i < 27; i++) {
if(chut[i] <= 0 || chut[i] > 26) {
chut[i] = 0;
}
}
printf("\nThe order input currently assigns adjacent students from the same team.\n");
printf("\nTeam Students\n");
for(i = 0; i < 27; i++) {
if(chut[i] != 0) {
printf("%d %d\n", i, chut[i]);
}
}
//1 2 3 3 4 5 6 7 8 9 1 2 3 4 5 5 7 8 9 1 2 3 4 5 6 7 8 8
}
return 0;
}
Basically for a given range of numbers, it checks if there is any particular number in the given entries that has an adjacent value which is the same as that number. If there is, it will just print how many times a particular element appeared in the given range of numbers.
Example - For a list of numbers
1 2 3 3 4 5 6 7 8 9 1 2 3 4 5 5 7 8 9 1 2 3 4 5 6 7 8 8
The program execution would be like -
Enter student section values: 1 2 3 3 5 6 7 8 9 1 2 3 4 5 5 7 8 9 1 2 3 4 5 6 7 8 8
The order input currently assigns adjacent students from the same team.
Team Students
1 3
2 3
3 4
4 2
5 4
6 2
7 3
8 4
9 2
Issue : I am not able to figure out the reason why the output is different on different machines and how I could fix that. For example, the output is correct on my Macbook running the program with XCode although it is different when I run it on a Linux machine with gcc compiler (Big Endian machine). I am not sure if the Endianess has anything to do with the outputs being different though.
On a Little Endian Linux machine -
On a Big Endian Linux machine -
On an online compiler (Tutorial's Point) -
The main problem, as far as I can see, is that you haven't initialized arrayBlank and are using it in:
arrayBlank[temp]++;
That certainly is cause for undefined behavior. I would initialize arrayBlank to zero using
int arrayBlank[100] = {0};
The secondary problem is that the loop counter to read the data is not right. Instead of:
while(counter != 27) {
scanf("%d", &responses[counter]);
use:
while(counter != 28) {
scanf("%d", &responses[counter]);
When you use counter != 27 to stop, the last element of responses, which can be accessed using index 27 is never read from file.

Resources