Code:
/*
You may delete this comment if you feel you do not need it.
This program is available for use under the General Public License and the GNU License.
You may copy, edit, cut, use any part or all of this source file or rewrite the code
contained therein, and republish it, as long as you do not use it for commercial purposes,
so that you may give back to the community.
-----------------------------------------------------------------------------------------
| |
| Sudoku Calculator |
| ============================================================================= |
| This program, aptly named, attempts to solve a sudoku puzzle already defined |
| in it. |
| I used a 9 x 9 array named 'sudoku[9][9]' to store the values of the sudoku |
| puzzle. The sudoku puzzle in question originally has 23 'exposed' cells. An |
| being solved. |
| |
| Go through the program to understand how it works. The code has hopefully been |
| comprehensively commented. |
| |
| Note: |
| ===== |
| My program's best answer so far is 47 'discovered cells', while obeying the |
| rules of sudoku, which if you add to 23 'exposed cells ' brings a total of 70 |
| 'known' cells. After this, it meets a dead end. |
| I tried to make it loop, when it meets a dead end, by making the function call |
| itself (iteration), reset the puzzle array values, and try a different route, |
| but that isn't still smart enough, because chances are high, it wil meet a dead end |
| again (I ran it in several instances). You can put any of the numbers 1 - 9 in 58 |
| (81 - 23) cells in different ways in any order. There are ((9 ^ 58) - x) wrong |
| ways, where x is the number of right ways and x is not very big, because of |
| restrictions (i.e Rules of Sudoku). |
| My knowlede(and experience) limits me, so I will garner more information on how |
| to solve difficult puzzles like the one I'm trying to solve and learn 'pointers' |
| properly for larger memory allocation and 'data structures' so that I can handle |
| data properly through the implementation of 'lists', 'queues' and the like and come |
| up with a better algorithm for solving any sudoku puzzle. You can try to see if you |
| can come up with a better solution. |
| You can compile and run this at any time. Cheers :D (Use 'Ctrl + C' to break) | |
----------------------------------------------------------------------------------------- |
*/
#include <stdio.h>
#include <stdlib.h>
// Most traditional c compilers don't support the boolean type, hence the type definition below.
#define TRUE 1 // Definition of constants for the boolean datatype.
#define FALSE 0
typedef int boolean;
// Functions' Prototypes
/**********************************************************************/
int main(void); //
void my_sudoku_func(void); //
void reset(void); // List of all the functions, //
void flush_cells(void); // I used in this program. //
void set_exposed_cells(void); //
void set_to_value_or_space(); //
void set_rows(void); //
void set_columns(void); //
void set_boxes(void); //
void set_all(void); //
void missing_numbers(void); //
int put_number(void); //
void try_for_number(int, int, int); //
boolean text_boxes(int); //
/*********************************************************************/
// Declarations of integer arrays to store values in the rows of the Sudoku.
int first_row[1][9], second_row[1][9], third_row[1][9],
fourth_row[1][9], fifth_row[1][9], sixth_row[1][9],
seventh_row[1][9], eight_row[1][9], ninth_row[1][9];
// Declarations of integer arrays to store values in the columns of the Sudoku.
int first_column[9][1], second_column[9][1], third_column[9][1],
fourth_column[9][1], fifth_column[9][1], sixth_column[9][1],
seventh_column[9][1], eight_column[9][1], ninth_column[9][1];
// Declarations of integer arrays to store values in the sub-grids (boxes) of the Sudoku.
int first_box[1][9], second_box[1][9], third_box[1][9],
fourth_box[1][9], fifth_box[1][9], sixth_box[1][9],
seventh_box[1][9], eight_box[1][9], ninth_box[1][9];
int sudoku[9][9];
// The function 'flush_cells()' below prevents the integer array 'sudoku[9][9]' stated above from holding
// garbage values by initializing the elements in the array to zero(0).
void flush_cells()
{
int i, j ;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
sudoku[i][j] = 0;
}
}
}
// This function sets the values of the 'exposed cells' of the Soduku puzzle in the integer array 'sudoku[9][9]'.
void set_exposed_cells()
{
/***First Row***/
sudoku[0][2] = 1;
sudoku[0][6] = 8;
/***Second Row****/
sudoku[1][1] = 5;
sudoku[1][4] = 1;
sudoku[1][7] = 4;
/***Third Row****/
sudoku[2][3] = 2;
sudoku[2][8] = 7;
/***Fourth Row****/
sudoku[3][2] = 7;
sudoku[3][5] = 5;
sudoku[3][7] = 8;
/***Fifth Row****/
sudoku[4][0] = 4;
sudoku[4][4] = 6;
sudoku[4][8] = 9;
/***Sixth Row****/
sudoku[5][1] = 2;
sudoku[5][3] = 4;
sudoku[5][6] = 5;
/***Seventh Row****/
sudoku[6][0] = 3;
sudoku[6][5] = 7;
/***Eight Row****/
sudoku[7][1] = 7;
sudoku[7][4] = 2;
sudoku[7][7] = 9;
/***Ninth Row****/
sudoku[8][2] = 4;
sudoku[8][6] = 1;
}
// This function tests to see if the suggested value from 'rand_number' is equal to any element in each of the boxes.
boolean test_boxes(int rand_r, int rand_c, int rand_number)
{
set_all(); // This sets all rows, columns, and boxes
// Check first box.
if (((rand_r >= 0) && (rand_r < 3)) && ((rand_c >= 0) && (rand_c < 3)))
{
return ((rand_number == first_box[0][0]) || (rand_number == first_box[0][1]) || (rand_number == first_box[0][2]) ||
(rand_number == first_box[0][3]) || (rand_number == first_box[0][4]) || (rand_number == first_box[0][5]) ||
(rand_number == first_box[0][6]) || (rand_number == first_box[0][7]) || (rand_number == first_box[0][8]));
}
// Check second box.
else if (((rand_r >= 0) && (rand_r < 3)) && ((rand_c >= 3) && (rand_c < 6)))
{
return((rand_number == second_box[0][0]) || (rand_number == second_box[0][1]) || (rand_number == second_box[0][2]) ||
(rand_number == second_box[0][3]) || (rand_number == second_box[0][4]) || (rand_number == second_box[0][5]) ||
(rand_number == second_box[0][6]) || (rand_number == second_box[0][7]) || (rand_number == second_box[0][8]));
}
// Check third box.
else if (((rand_r >= 0) && (rand_r < 3)) && ((rand_c >= 6) && (rand_c < 9)))
{
return((rand_number == third_box[0][0]) || (rand_number == third_box[0][1]) || (rand_number == third_box[0][2]) ||
(rand_number == third_box[0][3]) || (rand_number == third_box[0][4]) || (rand_number == third_box[0][5]) ||
(rand_number == third_box[0][6]) || (rand_number == third_box[0][7]) || (rand_number == third_box[0][8]));
}
// Check fourth box.
else if (((rand_r >= 3) && (rand_r <6)) && ((rand_c >= 0) && (rand_c < 3)))
{
return((rand_number == fourth_box[0][0]) || (rand_number == fourth_box[0][1]) || (rand_number == fourth_box[0][2]) ||
(rand_number == fourth_box[0][3]) || (rand_number == fourth_box[0][4]) || (rand_number == fourth_box[0][5]) ||
(rand_number == fourth_box[0][6]) || (rand_number == fourth_box[0][7]) || (rand_number == fourth_box[0][8]));
}
// Check fifth box.
else if (((rand_r >= 3) && (rand_r < 6)) && ((rand_c >= 3) && (rand_c < 6)))
{
return((rand_number == fourth_box[0][0]) || (rand_number == fourth_box[0][1]) || (rand_number == fourth_box[0][2]) ||
(rand_number == fourth_box[0][3]) || (rand_number == fourth_box[0][4]) || (rand_number == fourth_box[0][5]) ||
(rand_number == fourth_box[0][6]) || (rand_number == fourth_box[0][7]) || (rand_number == fourth_box[0][8]));
}
// Check sixth box.
else if (((rand_r >= 3) && (rand_r < 6)) && ((rand_c >= 6) && (rand_c < 9)))
{
return((rand_number == sixth_box[0][0]) || (rand_number == sixth_box[0][1]) || (rand_number == sixth_box[0][2]) ||
(rand_number == sixth_box[0][3]) || (rand_number == sixth_box[0][4]) || (rand_number == sixth_box[0][5]) ||
(rand_number == sixth_box[0][6]) || (rand_number == sixth_box[0][7]) || (rand_number == sixth_box[0][8]));
}
// Check seventh box.
else if (((rand_r >= 6) && (rand_r < 9)) && ((rand_c >= 0) && (rand_c < 3)))
{
return((rand_number == seventh_box[0][0]) || (rand_number == seventh_box[0][1]) || (rand_number == seventh_box[0][2]) ||
(rand_number == seventh_box[0][3]) || (rand_number == seventh_box[0][4]) || (rand_number == seventh_box[0][5]) ||
(rand_number == seventh_box[0][6]) || (rand_number == seventh_box[0][7]) || (rand_number == seventh_box[0][8]));
}
// Check eight box.
else if (((rand_r >= 6) && (rand_r < 9)) && ((rand_c >= 3) && (rand_c < 6)))
{
return((rand_number == eight_box[0][0]) || (rand_number == eight_box[0][1]) || (rand_number == eight_box[0][2]) ||
(rand_number == eight_box[0][3]) || (rand_number == eight_box[0][4]) || (rand_number == eight_box[0][5]) ||
(rand_number == eight_box[0][6]) || (rand_number == eight_box[0][7]) || (rand_number == eight_box[0][8]));
}
//Check ninth box.
else if (((rand_r >= 6) && (rand_r < 9)) && ((rand_c >= 6) && (rand_c < 9)))
{
return((rand_number == ninth_box[0][0]) || (rand_number == ninth_box[0][1]) || (rand_number == ninth_box[0][2]) ||
(rand_number == ninth_box[0][3]) || (rand_number == ninth_box[0][4]) || (rand_number == ninth_box[0][5]) ||
(rand_number == ninth_box[0][6]) || (rand_number == ninth_box[0][7]) || (rand_number == ninth_box[0][8]));
}
}
// This function tries to solve the sudoku puzzle by suggesting numbers from 1 - 9, as long as those numbers
// ar not used by any row, column or box
void try_for_number(int rand_r, int rand_c, int rand_number)
{
int empty = 0;
// This ensures that the random value we generate with 'rand()' are not signed (ie, they cannot be negative)
// and it changes with time.
srand((unsigned)time(0));
set_all();
if (sudoku[rand_r][rand_c] == empty)
{
do
{
set_exposed_cells();
set_all();
rand_r = (rand() % 9);
rand_c = (rand() % 9);
rand_number = (rand() % 9) + 1;
} while( // Test entire row for similar value with 'rand_number'.
((rand_number == sudoku[rand_r][0]) || (rand_number == sudoku[rand_r][1]) || (rand_number == sudoku[rand_r][2]) ||
(rand_number == sudoku[rand_r][3]) || (rand_number == sudoku[rand_r][4]) || (rand_number == sudoku[rand_r][5]) ||
(rand_number == sudoku[rand_r][6]) || (rand_number == sudoku[rand_r][7]) || (rand_number == sudoku[rand_r][8])) ||
//Test entire columnrow for similar value with 'rand_number'.
((rand_number == sudoku[0][rand_c]) || (rand_number == sudoku[1][rand_c]) || (rand_number == sudoku[2][rand_c]) ||
(rand_number == sudoku[3][rand_c]) || (rand_number == sudoku[4][rand_c]) || (rand_number == sudoku[5][rand_c]) ||
(rand_number == sudoku[6][rand_c]) || (rand_number == sudoku[7][rand_c]) || (rand_number == sudoku[8][rand_c])) || (test_boxes(rand_r, rand_c, rand_number) == 1));
}
set_exposed_cells();
set_all();
if( // Test entire row for similar value with 'rand_number'.
((rand_number != sudoku[rand_r][0]) && (rand_number != sudoku[rand_r][1]) && (rand_number != sudoku[rand_r][2]) &&
(rand_number != sudoku[rand_r][3]) && (rand_number != sudoku[rand_r][4]) && (rand_number != sudoku[rand_r][5]) &&
(rand_number != sudoku[rand_r][6]) && (rand_number != sudoku[rand_r][7]) && (rand_number != sudoku[rand_r][8]))
&&
//Test entire columnrow for similar value with 'rand_number'.
((rand_number != sudoku[0][rand_c]) && (rand_number != sudoku[1][rand_c]) && (rand_number != sudoku[2][rand_c]) &&
(rand_number != sudoku[3][rand_c]) && (rand_number != sudoku[4][rand_c]) && (rand_number != sudoku[5][rand_c]) &&
(rand_number != sudoku[6][rand_c]) && (rand_number != sudoku[7][rand_c]) && (rand_number != sudoku[8][rand_c])) && (test_boxes(rand_r, rand_c, rand_number) != 1))
{
// If no other cell has similar value with 'rand_number', then assign value of 'rand_number' to cell in question.
//sudoku[rand_r][rand_c] = rand_number;
sudoku[rand_r][rand_c] = rand_number;
set_exposed_cells();
set_all(); // This calls 'set_all()' which updates all rows, columns and boxes of the Sudoku table.
}
}
int put_number()
{
int j, k, l, count, tries = 0;
int sum[9]= {0, 0, 0, 0, 0, 0, 0, 0, 0};
long int i;
int rand_r = 0; // To hold row number.
int rand_c = 0; // To hold column value.
int rand_number = 0; // Arbitrary value from 1 to 9.
srand((unsigned)time(0));
//reset();
set_all();
for (i = 0; i < (9 ^ 58); i++) // First for loop
{
rand_r = (rand() % 9);
rand_c = (rand() % 9);
rand_number = (rand() % 9) + 1;
set_all();
try_for_number(rand_r, rand_c, rand_number); // This calls 'try_for_number()'.
}
//set_exposed_cells();
set_all();
set_to_value_or_space();
for (count = 0; count < 9; count++)
{
sum[0] += first_box[0][count];
sum[1] += second_box[0][count];
sum[2] += third_box[0][count];
sum[3] += fourth_box[0][count];
sum[4] += fourth_box[0][count];
sum[5] += sixth_box[0][count];
sum[6] += seventh_box[0][count];
sum[7] += eight_box[0][count];
sum[8] += ninth_box[0][count];
}
if (sum[0] != 45 && sum[1] != 45 && sum[2] != 45 && sum[3] != 45 && sum[4] != 45 &&
sum[5] != 45 && sum[6] != 45 && sum[7] != 45 && sum[8] != 45)
{
//reset();
set_all();
printf("....still solving...");
put_number();
}
else if (sum[0] == 45 && sum[1] == 45 && sum[2] == 45 && sum[3] == 45 && sum[4] == 45 &&
sum[5] == 45 && sum[6] == 45 && sum[7] == 45 && sum[8] == 45)
{
printf("done!");
getchar();
return 0;
}
else
{
printf("tried %d", ++tries);
printf("trying again...");
reset();
set_all();
put_number();
getchar();
return 0;
}
}
void set_all()
{
set_rows();
set_columns();
set_boxes();
}
//The function 'reset()' below, simply calls two other functions; 'flush_cells()' and 'set_exposed_cells()'.
void reset()
{
flush_cells();
set_exposed_cells();
}
// The function 'set_rows()' below, passes all values from the rows of the sudoku table to the array
// variables below.
void set_rows()
{
int i, j;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
if (i == 0)
{ first_row[i][j] = sudoku[i][j]; }
else if (i == 1)
{ second_row[i][j] = sudoku[i][j]; }
else if (i == 2)
{ third_row[i][j] = sudoku[i][j]; }
else if (i == 3)
{ fourth_row[i][j] = sudoku[i][j]; }
else if (i == 4)
{ fifth_row[i][j] = sudoku[i][j]; }
else if (i == 5)
{ sixth_row[i][j] = sudoku[i][j]; }
else if (i == 6)
{ seventh_row[i][j] = sudoku[i][j]; }
else if (i == 7)
{ eight_row[i][j] = sudoku[i][j]; }
else if (i == 8)
{ ninth_row[i][j] = sudoku[i][j]; }
}
}
}
// This function pass all values from the columns of the sudoku table to the array
// variables below.
void set_columns()
{
int i, j;
for (j = 0; j < 9; j++)
{
for (i = 0; i < 9; i++)
{
if (i == 0)
{ first_column[i][j] = sudoku[i][j]; }
else if (i == 1)
{ second_column[i][j] = sudoku[i][j]; }
else if (i == 2)
{ third_column[i][j] = sudoku[i][j]; }
else if (i == 3)
{ fourth_column[i][j] = sudoku[i][j]; }
else if (i == 4)
{ fifth_column[i][j] = sudoku[i][j]; }
else if (i == 5)
{ sixth_column[i][j] = sudoku[i][j]; }
else if (i == 6)
{ seventh_column[i][j] = sudoku[i][j]; }
else if (i == 7)
{ eight_column[i][j] = sudoku[i][j]; }
else if (i == 8)
{ ninth_column[i][j] = sudoku[i][j]; }
}
}
}
// This funtion passes values from the sub-grids(boxes) of the sudoku table to the elements of the array variables contained in it.
void set_boxes()
{
// These declarations and initializations pass all values from the sub-grids(boxes) of the
// sudoku table to the elements of the array variables below.
first_box[0][0] = sudoku[0][0];
first_box[0][1] = sudoku[0][1];
first_box[0][2] = sudoku[0][2];
first_box[0][3] = sudoku[1][0];
first_box[0][4] = sudoku[1][1];
first_box[0][5] = sudoku[1][2];
first_box[0][6] = sudoku[2][0];
first_box[0][7] = sudoku[2][1];
first_box[0][8] = sudoku[2][2];
second_box[0][0] = sudoku[0][3];
second_box[0][1] = sudoku[0][4];
second_box[0][2] = sudoku[0][5];
second_box[0][3] = sudoku[1][3];
second_box[0][4] = sudoku[1][4];
second_box[0][5] = sudoku[1][5];
second_box[0][6] = sudoku[2][3];
second_box[0][7] = sudoku[2][4];
second_box[0][8] = sudoku[2][5];
third_box[0][0] = sudoku[0][6];
third_box[0][1] = sudoku[0][7];
third_box[0][2] = sudoku[0][8];
third_box[0][3] = sudoku[1][6];
third_box[0][4] = sudoku[1][7];
third_box[0][5] = sudoku[1][8];
third_box[0][6] = sudoku[2][6];
third_box[0][7] = sudoku[2][7];
third_box[0][8] = sudoku[2][8];
fourth_box[0][0] = sudoku[3][0];
fourth_box[0][1] = sudoku[3][1];
fourth_box[0][2] = sudoku[3][2];
fourth_box[0][3] = sudoku[4][0];
fourth_box[0][4] = sudoku[4][1];
fourth_box[0][5] = sudoku[4][2];
fourth_box[0][6] = sudoku[5][0];
fourth_box[0][7] = sudoku[5][1];
fourth_box[0][8] = sudoku[5][2];
fifth_box[0][0] = sudoku[3][3];
fifth_box[0][1] = sudoku[3][4];
fifth_box[0][2] = sudoku[3][5];
fifth_box[0][3] = sudoku[4][3];
fifth_box[0][4] = sudoku[4][4];
fifth_box[0][5] = sudoku[4][5];
fifth_box[0][6] = sudoku[5][3];
fifth_box[0][7] = sudoku[5][4];
fifth_box[0][8] = sudoku[5][5];
sixth_box[0][0] = sudoku[3][6];
sixth_box[0][1] = sudoku[3][7];
sixth_box[0][2] = sudoku[3][8];
sixth_box[0][3] = sudoku[4][6];
sixth_box[0][4] = sudoku[4][7];
sixth_box[0][5] = sudoku[4][8];
sixth_box[0][6] = sudoku[5][6];
sixth_box[0][7] = sudoku[5][7];
sixth_box[0][8] = sudoku[5][8];
seventh_box[0][0] = sudoku[6][0];
seventh_box[0][1] = sudoku[6][1];
seventh_box[0][2] = sudoku[6][2];
seventh_box[0][3] = sudoku[7][0];
seventh_box[0][4] = sudoku[7][1];
seventh_box[0][5] = sudoku[7][2];
seventh_box[0][6] = sudoku[8][0];
seventh_box[0][7] = sudoku[8][1];
seventh_box[0][8] = sudoku[8][2];
eight_box[0][0] = sudoku[6][3];
eight_box[0][1] = sudoku[6][4];
eight_box[0][2] = sudoku[6][5];
eight_box[0][3] = sudoku[7][3];
eight_box[0][4] = sudoku[7][4];
eight_box[0][5] = sudoku[7][5];
eight_box[0][6] = sudoku[8][3];
eight_box[0][7] = sudoku[8][4];
eight_box[0][8] = sudoku[8][5];
ninth_box[0][0] = sudoku[6][6];
ninth_box[0][1] = sudoku[6][7];
ninth_box[0][2] = sudoku[6][8];
ninth_box[0][3] = sudoku[7][6];
ninth_box[0][4] = sudoku[7][7];
ninth_box[0][5] = sudoku[7][8];
ninth_box[0][6] = sudoku[8][6];
ninth_box[0][7] = sudoku[8][7];
ninth_box[0][8] = sudoku[8][8];
}
// This function displays in grids, the Sudoku table and for 'non-exposed' cells, and prints a blank space
// in the place of array values of zero.
void set_to_value_or_space()
{
int i, j, k = 0, count = 0; // Declaratioin and Initialization of variables.
char response;
set_exposed_cells(); // This calls 'set_exposed_cells' which assigns the original values of the 'exposed cells'.
// This for loop finds the number of exposed cells
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
if (sudoku[i][j] != 0) // This checks to see if the cell in question does not contains zero(0) as its value.
{
count++;
}
}
}
// The following printf() functions prints strings and escape sequences just like in any other c program.
printf("\n\nSudoku sorter: The table below has %d", count);
printf(" exposed cells:");
printf("\n\n\n\t\t\t ---Original Table---\n\n");
printf("\t\t___________________________________________");
printf("\n\t\t ___________ ___________ ___________ ");printf("\n");
for (i = 0; i < 9; i++)
{
k = 0;
printf("\t\t ");
printf("| ");printf("| ");printf("| ");printf("| ");printf("| ");printf("| ");printf("| ");printf("| ");printf("| ");printf("| ");printf("| ");printf("| ");printf("\n");
if (k == 0)
{
printf("\t\t ");
for (j = 0; j < 3; j++)
{
if (sudoku[i][j] == 0)
{
printf("| ");printf(" ");printf(" ");
}
else
{
printf("| %d", sudoku[i][j]);printf(" ");
}
}
printf("|");
k += 4;
}
if (k == 4)
{
printf(" ");
for (j = 3; j < 6; j++)
{
if (sudoku[i][j] == 0)
{
printf("| ");printf(" ");printf(" ");
}
else
{
printf("| %d", sudoku[i][j]);printf(" ");
}
}
printf("|");
k += 4;
}
if (k == 8)
{
printf(" ");
for (j = 6; j < 9; j++)
{
if (sudoku[i][j] == 0)
{
printf("| ");printf(" ");printf(" ");
}
else
{
printf("| %d", sudoku[i][j]);printf(" ");
}
}
printf("|");
printf("\n\t\t |___|___|___| |___|___|___| |___|___|___|\n");
}
if (i == 2 || i == 5)
{
printf("\n");
printf("\t\t ___________ ___________ ___________\t\n");
}
}
printf("\t\t___________________________________________\n\n");
}
void my_sudoku_func()
{
reset(); // This calls 'reset()' which assigns the original values of the 'exposed cells'.
set_to_value_or_space(); // This calls 'set_to_value_or_space()' which prints out the values of the Sudoku table on the screen.
put_number(); // This calls 'put_number()' which tries to solve the sudoku table.
}
int main()
{
my_sudoku_func(); // This calls 'my_sudoku_func()' which is above.
return 0;
}