Commit 306b5bd5 authored by nrossol's avatar nrossol
Browse files

Almost finished implementing python version.

parent eb8e7347
//Recursive backtracking algorithm that can solve any sudoku puzzle.
//Created by Nathan Rossol 8/16/20
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <set> #include <set>
//Backtracking & recursive algorithm to solve sudoku puzzle if possible, to be implemented in python with a GUI later.
//Main Algorithm:
bool solveSudoku(int (&grid)[9][9]);
//Helper Functions:
bool checkBox(const int (&grid)[9][9], const int &row, const int &col);
bool checkSolution(const int (&grid)[9][9], const int &row, const int &col);
bool findZero(const int (&grid)[9][9], std::pair<int,int> &zeroIndex);
void printBoard(const int (&grid)[9][9]);
void solve(int (&grid)[9][9]);
/////////Main/////////
int main(int argc, char *argv[]) {
//basic error checking:
if(argc != 2 ){
std::cout << "[ERROR] Correct Use: ./sudokuSolver.exe [grid number 1-3]" << std::endl;
return -1;
}
std::string arg = argv[1];
if (arg != "1" && arg != "2" && arg != "3") {
std::cout << "[ERROR] Correct Use: ./sudokuSolver.exe [grid number 1-3]" << std::endl;
return -1;
}
//grid selection:
if(arg == "1"){
int grid[9][9] = { { 3, 2, 1, 0, 5, 0, 9, 4, 7 },
{7, 8, 0, 0, 1, 0, 0, 6, 5},
{0, 0, 6, 7, 0, 4, 1, 0, 0},
{5, 4, 9, 0, 0, 0, 7, 8 ,6},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 9, 0, 6, 0, 0, 0},
{1, 0, 5, 0, 6, 0, 4, 0, 2},
{0 ,3 ,0, 2, 0, 7, 0, 5, 0},
{2, 0, 7, 0, 4, 0, 8, 0, 3} };
solve(grid);
} else if (arg == "2"){
int grid[9][9] = { {1, 0, 0, 3, 0, 0, 0, 8, 0},
{3, 0, 0, 9, 0, 0, 6, 0, 0},
{0, 0, 0, 7, 4, 8, 1, 0, 5},
{4, 2, 6, 0, 0, 0, 7, 0, 0},
{0, 7, 8, 4, 0, 9, 3, 6, 0},
{0, 0, 3, 0, 0, 0, 4, 5, 8},
{2, 0, 1, 8, 9, 4, 0, 0, 0},
{0, 0, 4, 0, 0, 6, 0, 0, 9},
{0, 3, 0, 0, 0, 5, 0, 0, 6} };
solve(grid);
} else if (arg == "3"){
int grid[9][9] = { {0, 0, 0, 4, 9, 0, 1, 5, 0},
{2, 9, 0, 7, 1, 0, 6, 8, 0},
{6, 1, 0, 0, 8, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 7, 0, 2, 6},
{9, 3, 2, 0, 0, 0, 4, 7, 1},
{1, 7, 0, 9, 0, 4, 0, 0, 0},
{0, 0, 0, 0, 7, 0, 0, 6, 4},
{0, 6, 9, 0, 4, 3, 0, 1, 5},
{0, 2, 3, 0, 5, 1, 0, 0, 0} };
solve(grid);
}
return 0;
}
/////////Main Solving Algorithm/////////
//Sudoku rules: The grid has 81 squares: 9 boxes of 9 squares. Each box must contain //Sudoku rules: The grid has 81 squares: 9 boxes of 9 squares. Each box must contain
//all numbers 1-9 in its squares, and each number can appear only once in any row, //all numbers 1-9 in its squares, and each number can appear only once in any row,
//column, or box. //column, or box.
bool solveSudoku(int **grid){ bool solveSudoku(int (&grid)[9][9]){
std::pair<int,int> zeroIndex; //row,col of the zero to be filled. std::pair<int,int> zeroIndex; //row,col of the zero to be filled.
bool foundZero = findZero(grid, zeroIndex); bool foundZero = findZero(grid, zeroIndex);
bool solved;
if(foundZero){ if(foundZero){
for(int i = 1; i < 10; ++i){ for(int i = 1; i < 10; ++i){
grid[zeroIndex.first,zeroIndex.second] = i; grid[zeroIndex.first][zeroIndex.second] = i;
if(checkSolution(grid, zeroIndex.first, zeroIndex.second)){ if(checkSolution(grid, zeroIndex.first, zeroIndex.second)){
solveSudoku(grid); // std::cout<< zeroIndex.first << ", " << zeroIndex.second << " == " << grid[zeroIndex.first][zeroIndex.second] << std::endl;
solved = solveSudoku(grid);
if(solved) {return true;}
} }
} }
grid[zeroIndex.first,zeroIndex.second] = 0;
grid[zeroIndex.first][zeroIndex.second] = 0;
return false; return false;
} else { } else {
return true; //solved return true; //solved
} }
}
/////////Helper functions/////////
//checks the boxes to assure no duplicate numbers
bool checkBox(const int (&grid)[9][9], const int &row, const int &col){
std::set<int> numbers;
for(int i = 0; i < 3; ++i){
for(int j = 0; j < 3; ++j){
//std::cout << "ROW, COL: " << row+i << " ," << col + j << std::endl;
if(numbers.insert(grid[row+i][col+j]).second == false && grid[row+i][col+j] != 0) { //duplicate detected!
//std::cout << "DUPLICATE!" << std::endl;
return false;
}
}
}
return true;
} }
//Helper functions:
//checks the solution for a given index and returns true if valid. //checks the solution for a given index and returns true if valid.
bool checkSolution(int **grid, const int &row, const int &col){ bool checkSolution(const int (&grid)[9][9], const int &row, const int &col){
//check cols and rows:
for(int i = 0; i < 9; ++i){ for(int i = 0; i < 9; ++i){
if(grid[i][col] == grid[row][col] && i != row) { if(grid[i][col] == grid[row][col] && i != row) {
return false; return false;
...@@ -34,11 +125,20 @@ bool checkSolution(int **grid, const int &row, const int &col){ ...@@ -34,11 +125,20 @@ bool checkSolution(int **grid, const int &row, const int &col){
return false; return false;
} }
} }
//check boxes:
for(int i = 0; i < 9; i += 3){
for(int j = 0; j < 9; j += 3){
if(!checkBox(grid,i,j)) {return false;}
}
}
return true; return true;
} }
//Finds the index of the next zero to be solved. //Finds the index of the next zero to be solved.
bool findZero(int **grid, std::pair<int,int> &zeroIndex){ bool findZero(const int (&grid)[9][9], std::pair<int,int> &zeroIndex){
for(int i = 0; i < 9; ++i){ for(int i = 0; i < 9; ++i){
for(int j = 0; j < 9; ++j){ for(int j = 0; j < 9; ++j){
if(grid[i][j] == 0) { if(grid[i][j] == 0) {
...@@ -53,35 +153,19 @@ bool findZero(int **grid, std::pair<int,int> &zeroIndex){ ...@@ -53,35 +153,19 @@ bool findZero(int **grid, std::pair<int,int> &zeroIndex){
} }
//Prints the board. //Prints the board.
void printBoard(){ void printBoard(const int (&grid)[9][9]){
for(int i = 0; i < 9; ++i){ for(int i = 0; i < 9; ++i){
for(int j = 0; j < 9; ++j){ for(int j = 0; j < 9; ++j){
std::cout << grid{i][j] << " ";} std::cout << grid[i][j] << " ";
} }
std::cout << std::endl; std::cout << std::endl;
} }
} }
int main() { //Executes the algorithm:
//Easy Grid: void solve(int (&grid)[9][9]) {
int grid[9][9] = { { 1, 2, 3, 0, 5, 6 ,7 ,8, 9 },
{0, 5, 6, 7, 8, 9, 1, 2, 3},
{7, 8, 0, 1, 2, 3, 4, 5, 6},
{2, 1, 4, 3, 6, 5, 0, 9 ,7},
{3, 0, 5, 8, 9, 7, 2, 1,4},
{8, 9, 7, 2, 1, 4, 3, 6, 0},
{5, 3, 1, 6, 4, 2, 9, 0, 8},
{6 ,4 ,2, 9, 0, 8, 5, 3, 1},
{9, 7, 8, 0, 3, 1, 6, 4, 2} };
//Medium Grid:
//Hard Grid:
if(solveSudoku(grid)==true) {std::cout << "Solved!" << std::endl;} if(solveSudoku(grid)==true) {std::cout << "Solved!" << std::endl;}
else {std::cout << "Unsolvable :(" << std::endl;} else {std::cout << "Unsolvable :(" << std::endl;}
printBoard(); printBoard(grid);
}
return 0;
}
\ No newline at end of file
#Recursive/backtracking algorithm to solve sudoku puzzle if possible.
#By Nathan Rossol, Computer Science sophomore at the University of Michigan
grid = ([[1,2,3,0,5,6,7,8,9],
[0,5,6,7,8,9,1,2,3],
[7,8,0,1,2,3,4,5,6],
[2,1,4,3,6,5,0,9,7],
[3,0,5,8,9,7,2,1,4],
[8,9,7,2,1,4,3,6,0],
[5,3,1,6,4,2,9,0,8],
[6,4,2,9,0,8,5,3,1],
[9,7,8,0,3,1,6,4,2]
])
#Game rules: The grid has 81 squares: 9 boxes of 9 squares. Each box must contain
#all numbers 1-9 in its squares, and each number can appear only once in any row,
#column, or box.
solve(grid)
def solveSudoku(grid):
zeroIndex = (0,0)
foundZero = findZero(grid, zeroIndex)
solved = False
if foundZero:
for i in range(1,9):
grid[zeroIndex[0]][zeroIndex[1]] = i
if(checkSolution(grid,zeroIndex[0],zeroIndex[1])):
solved = solveSudoku(grid)
if(solved): return True
grid[zeroIndex[0]][zeroIndex[1]] = 0
return False
else:
return True
def checkBox(grid, row, col):
numbers = []
for i in range(row,row+2):
for j in range(col,col+2):
if grid[i][j] not in numbers: numbers.insert(grid[i][j])
else: return False
return True
def checkSolution(grid, row, col):
#check cols and rows:
for i in range(0,8):
if grid[i][col] == grid[row][col] and i != row:
return False
elif grid[row][i] == grid[row][col] and i != col:
return False
#check boxes:
for i in range(0,8,3):
for j in range(0,8,3):
if not checkBox(grid,i,j):
return False
return True
def findZero(grid, zeroIndex):
found = False
for r in grid:
for c in r:
if grid[r][c] == 0:
zeroIndex[0] = r
zeroIndex[1] = c
found = True
return found
def printBoard(grid):
for i in range(0,8):
for j in range(0,8):
print(grid[i][j], end=' ')
print()
def solve(grid):
if solveSudoku(grid):
print("SOLVED!")
else:
print("Unsolvable :(")
printBoard(grid)
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment