/* A C++ program designed to solve sudoku puzzles. The program finds blank spaces
* on the 9x9 grid and tests for the first value from 1 to 9 that can be placed
* in the square. There must be the number 1 through 9 in every row, column,
* and 3x3 box. If the program later finds a problem trying to place values in
* blank boxes, it goes back and unassigns values to the recently assigned
* boxes. This program was written for the CS 173 Spring 2014 honors project
* by Erin Emrath. */
#include <stdio.h>
// UNASSIGNED is used for blank spaces in the sudoku grid
#define UNASSIGNED 0
bool FindEmptySpace(int grid[9][9], int &row, int &col);
bool isLegal(int grid[9][9], int row, int col, int num);
bool SolveSudoku(int grid[9][9])
{
int row, col;
// If there are no empty spaces, the puzzle is solved.
if (!FindEmptySpace(grid, row, col))
return true;
// try integers 1 through 9
for (int num = 1; num <= 9; num++)
{
// checks that the number isn't in the corresponding row, column, or box.
if (isLegal(grid, row, col, num))
{
// make preliminary guess
grid[row][col] = num;
// The grid is solved
if (SolveSudoku(grid))
return true;
// failure, unassign previous value and try a different number
grid[row][col] = UNASSIGNED;
}
}
return false; // the program goes back to try a higher value than before
}
/* Searches the grid to find a space that is still empty. If
one is found, the variables row and col will be set to the
empty space and then true is returned. If there are no empty
spaces left, false is returned. */
bool FindEmptySpace(int grid[9][9], int &row, int &col)
{
for (row = 0; row < 9; row++)
for (col = 0; col < 9; col++)
if (grid[row][col] == UNASSIGNED)
return true;
return false;
}
/* Returns a boolean indicating whether any assigned value
in the specified row matches the given number. Similar
for the following column and box methods. */
bool InSameRow(int grid[9][9], int row, int num)
{
for (int col = 0; col < 9; col++)
if (grid[row][col] == num)
return true;
return false;
}
bool InSameCol(int grid[9][9], int col, int num)
{
for (int row = 0; row < 9; row++)
if (grid[row][col] == num)
return true;
return false;
}
bool InSameBox(int grid[9][9], int boxStartRow, int boxStartCol, int num)
{
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
if (grid[row+boxStartRow][col+boxStartCol] == num)
return true;
return false;
}
/* Returns a boolean indicating whether it will be legal to fill
the given row, col, and box location with num. */
bool isLegal(int grid[9][9], int row, int col, int num)
{
return !InSameRow(grid, row, num) &&
!InSameCol(grid, col, num) &&
!InSameBox(grid, row - row%3 , col - col%3, num);
}
/* print solved grid */
void printGrid(int grid[9][9])
{
for (int row = 0; row < 9; row++)
{
for (int col = 0; col < 9; col++)
printf("%2d", grid[row][col]);
printf("\n");
}
}
/* main program, implementation */
int main()
{
// 0 means empty spaces
int grid[9][9] = {{1,0,9,0,0,0,0,0,0},
{0,0,5,0,0,0,1,2,0},
{6,0,0,0,0,4,0,0,0},
{0,1,0,0,0,9,0,0,0},
{0,0,0,0,3,7,0,0,0},
{7,0,0,0,0,1,2,0,0},
{0,0,0,0,0,0,3,0,8},
{0,0,0,3,0,0,9,0,0},
{0,0,8,0,0,0,0,6,0}};
if (SolveSudoku(grid) == true)
printGrid(grid);
else
printf("Puzzle has no solution");
return 0;
}
LyogICAgQSBDKysgcHJvZ3JhbSBkZXNpZ25lZCB0byBzb2x2ZSBzdWRva3UgcHV6emxlcy4gVGhlIHByb2dyYW0gZmluZHMgYmxhbmsgc3BhY2VzCiAqICAgIG9uIHRoZSA5eDkgZ3JpZCBhbmQgdGVzdHMgZm9yIHRoZSBmaXJzdCB2YWx1ZSBmcm9tIDEgdG8gOSB0aGF0IGNhbiBiZSBwbGFjZWQKICogICAgaW4gdGhlIHNxdWFyZS4gVGhlcmUgbXVzdCBiZSB0aGUgbnVtYmVyIDEgdGhyb3VnaCA5IGluIGV2ZXJ5IHJvdywgY29sdW1uLAogKiAgICBhbmQgM3gzIGJveC4gSWYgdGhlIHByb2dyYW0gbGF0ZXIgZmluZHMgYSBwcm9ibGVtIHRyeWluZyB0byBwbGFjZSB2YWx1ZXMgaW4KICogICAgYmxhbmsgYm94ZXMsIGl0IGdvZXMgYmFjayBhbmQgdW5hc3NpZ25zIHZhbHVlcyB0byB0aGUgcmVjZW50bHkgYXNzaWduZWQgCiAqICAgIGJveGVzLiBUaGlzIHByb2dyYW0gd2FzIHdyaXR0ZW4gZm9yIHRoZSBDUyAxNzMgU3ByaW5nIDIwMTQgaG9ub3JzIHByb2plY3QgCiAqICAgIGJ5IEVyaW4gRW1yYXRoLiAgKi8KI2luY2x1ZGUgPHN0ZGlvLmg+CgovLyBVTkFTU0lHTkVEIGlzIHVzZWQgZm9yIGJsYW5rIHNwYWNlcyBpbiB0aGUgc3Vkb2t1IGdyaWQKI2RlZmluZSBVTkFTU0lHTkVEIDAKCmJvb2wgRmluZEVtcHR5U3BhY2UoaW50IGdyaWRbOV1bOV0sIGludCAmcm93LCBpbnQgJmNvbCk7Cgpib29sIGlzTGVnYWwoaW50IGdyaWRbOV1bOV0sIGludCByb3csIGludCBjb2wsIGludCBudW0pOwoKYm9vbCBTb2x2ZVN1ZG9rdShpbnQgZ3JpZFs5XVs5XSkKewogICAgaW50IHJvdywgY29sOwoKICAgIC8vIElmIHRoZXJlIGFyZSBubyBlbXB0eSBzcGFjZXMsIHRoZSBwdXp6bGUgaXMgc29sdmVkLgogICAgaWYgKCFGaW5kRW1wdHlTcGFjZShncmlkLCByb3csIGNvbCkpCiAgICAgICByZXR1cm4gdHJ1ZTsgCgogICAgLy8gdHJ5IGludGVnZXJzIDEgdGhyb3VnaCA5CiAgICBmb3IgKGludCBudW0gPSAxOyBudW0gPD0gOTsgbnVtKyspCiAgICB7CiAgICAgICAgLy8gY2hlY2tzIHRoYXQgdGhlIG51bWJlciBpc24ndCBpbiB0aGUgY29ycmVzcG9uZGluZyByb3csIGNvbHVtbiwgb3IgYm94LgogICAgICAgIGlmIChpc0xlZ2FsKGdyaWQsIHJvdywgY29sLCBudW0pKQogICAgICAgIHsKICAgICAgICAgICAgLy8gbWFrZSBwcmVsaW1pbmFyeSBndWVzcwogICAgICAgICAgICBncmlkW3Jvd11bY29sXSA9IG51bTsKCiAgICAgICAgICAgIC8vIFRoZSBncmlkIGlzIHNvbHZlZAogICAgICAgICAgICBpZiAoU29sdmVTdWRva3UoZ3JpZCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgIC8vIGZhaWx1cmUsIHVuYXNzaWduIHByZXZpb3VzIHZhbHVlIGFuZCB0cnkgYSBkaWZmZXJlbnQgbnVtYmVyCiAgICAgICAgICAgIGdyaWRbcm93XVtjb2xdID0gVU5BU1NJR05FRDsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7IC8vIHRoZSBwcm9ncmFtIGdvZXMgYmFjayB0byB0cnkgYSBoaWdoZXIgdmFsdWUgdGhhbiBiZWZvcmUKfQoKLyogU2VhcmNoZXMgdGhlIGdyaWQgdG8gZmluZCBhIHNwYWNlIHRoYXQgaXMgc3RpbGwgZW1wdHkuIElmCiAgIG9uZSBpcyBmb3VuZCwgdGhlIHZhcmlhYmxlcyByb3cgYW5kIGNvbCB3aWxsIGJlIHNldCB0byB0aGUgCiAgIGVtcHR5IHNwYWNlIGFuZCB0aGVuIHRydWUgaXMgcmV0dXJuZWQuIElmIHRoZXJlIGFyZSBubyBlbXB0eQogICBzcGFjZXMgbGVmdCwgZmFsc2UgaXMgcmV0dXJuZWQuICovCmJvb2wgRmluZEVtcHR5U3BhY2UoaW50IGdyaWRbOV1bOV0sIGludCAmcm93LCBpbnQgJmNvbCkKewogICAgZm9yIChyb3cgPSAwOyByb3cgPCA5OyByb3crKykKICAgICAgICBmb3IgKGNvbCA9IDA7IGNvbCA8IDk7IGNvbCsrKQogICAgICAgICAgICBpZiAoZ3JpZFtyb3ddW2NvbF0gPT0gVU5BU1NJR05FRCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZhbHNlOwp9CgovKiBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgYW55IGFzc2lnbmVkIHZhbHVlCiAgIGluIHRoZSBzcGVjaWZpZWQgcm93IG1hdGNoZXMgdGhlIGdpdmVuIG51bWJlci4gU2ltaWxhciAKICAgZm9yIHRoZSBmb2xsb3dpbmcgY29sdW1uIGFuZCBib3ggbWV0aG9kcy4gKi8KYm9vbCBJblNhbWVSb3coaW50IGdyaWRbOV1bOV0sIGludCByb3csIGludCBudW0pCnsKICAgIGZvciAoaW50IGNvbCA9IDA7IGNvbCA8IDk7IGNvbCsrKQogICAgICAgIGlmIChncmlkW3Jvd11bY29sXSA9PSBudW0pCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZhbHNlOwp9Cgpib29sIEluU2FtZUNvbChpbnQgZ3JpZFs5XVs5XSwgaW50IGNvbCwgaW50IG51bSkKewogICAgZm9yIChpbnQgcm93ID0gMDsgcm93IDwgOTsgcm93KyspCiAgICAgICAgaWYgKGdyaWRbcm93XVtjb2xdID09IG51bSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICByZXR1cm4gZmFsc2U7Cn0KCmJvb2wgSW5TYW1lQm94KGludCBncmlkWzldWzldLCBpbnQgYm94U3RhcnRSb3csIGludCBib3hTdGFydENvbCwgaW50IG51bSkKewogICAgZm9yIChpbnQgcm93ID0gMDsgcm93IDwgMzsgcm93KyspCiAgICAgICAgZm9yIChpbnQgY29sID0gMDsgY29sIDwgMzsgY29sKyspCiAgICAgICAgICAgIGlmIChncmlkW3Jvdytib3hTdGFydFJvd11bY29sK2JveFN0YXJ0Q29sXSA9PSBudW0pCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIHJldHVybiBmYWxzZTsKfQoKLyogUmV0dXJucyBhIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGl0IHdpbGwgYmUgbGVnYWwgdG8gZmlsbCAKICAgdGhlIGdpdmVuIHJvdywgY29sLCBhbmQgYm94IGxvY2F0aW9uIHdpdGggbnVtLiAqLwpib29sIGlzTGVnYWwoaW50IGdyaWRbOV1bOV0sIGludCByb3csIGludCBjb2wsIGludCBudW0pCnsKICAgIHJldHVybiAhSW5TYW1lUm93KGdyaWQsIHJvdywgbnVtKSAmJgogICAgICAgICAgICFJblNhbWVDb2woZ3JpZCwgY29sLCBudW0pICYmCiAgICAgICAgICAgIUluU2FtZUJveChncmlkLCByb3cgLSByb3clMyAsIGNvbCAtIGNvbCUzLCBudW0pOwp9CgovKiBwcmludCBzb2x2ZWQgZ3JpZCAgKi8Kdm9pZCBwcmludEdyaWQoaW50IGdyaWRbOV1bOV0pCnsKICAgIGZvciAoaW50IHJvdyA9IDA7IHJvdyA8IDk7IHJvdysrKQogICAgewogICAgICAgZm9yIChpbnQgY29sID0gMDsgY29sIDwgOTsgY29sKyspCiAgICAgICAgICAgICBwcmludGYoIiUyZCIsIGdyaWRbcm93XVtjb2xdKTsKICAgICAgICBwcmludGYoIlxuIik7CiAgICB9Cn0KCi8qIG1haW4gcHJvZ3JhbSwgaW1wbGVtZW50YXRpb24gKi8KaW50IG1haW4oKQp7CiAgICAvLyAwIG1lYW5zIGVtcHR5IHNwYWNlcwogICAgaW50IGdyaWRbOV1bOV0gPSB7ezEsMCw5LDAsMCwwLDAsMCwwfSwKCQkgICAgICB7MCwwLDUsMCwwLDAsMSwyLDB9LAoJCSAgICAgIHs2LDAsMCwwLDAsNCwwLDAsMH0sCgkJICAgICAgezAsMSwwLDAsMCw5LDAsMCwwfSwKCQkgICAgICB7MCwwLDAsMCwzLDcsMCwwLDB9LAoJCSAgICAgIHs3LDAsMCwwLDAsMSwyLDAsMH0sCgkJICAgICAgezAsMCwwLDAsMCwwLDMsMCw4fSwKCQkgICAgICB7MCwwLDAsMywwLDAsOSwwLDB9LAoJCSAgICAgIHswLDAsOCwwLDAsMCwwLDYsMH19OwoKICAgIGlmIChTb2x2ZVN1ZG9rdShncmlkKSA9PSB0cnVlKQogICAgICAgICAgcHJpbnRHcmlkKGdyaWQpOwogICAgZWxzZQogICAgICAgICBwcmludGYoIlB1enpsZSBoYXMgbm8gc29sdXRpb24iKTsKCiAgICByZXR1cm4gMDsKfQ==