Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
nrossol
Sudoku Backtracking
Commits
306b5bd5
Commit
306b5bd5
authored
Aug 27, 2020
by
nrossol
Browse files
Almost finished implementing python version.
parent
eb8e7347
Changes
2
Hide whitespace changes
Inline
Side-by-side
sudokuSolver.cpp
View file @
306b5bd5
//Recursive backtracking algorithm that can solve any sudoku puzzle.
//Created by Nathan Rossol 8/16/20
#include
<iostream>
#include
<map>
#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
//all numbers 1-9 in its squares, and each number can appear only once in any row,
//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.
bool
foundZero
=
findZero
(
grid
,
zeroIndex
);
bool
solved
;
if
(
foundZero
){
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
)){
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
;
}
else
{
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.
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
){
if
(
grid
[
i
][
col
]
==
grid
[
row
][
col
]
&&
i
!=
row
)
{
return
false
;
...
...
@@ -34,11 +125,20 @@ bool checkSolution(int **grid, const int &row, const int &col){
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
;
}
//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
j
=
0
;
j
<
9
;
++
j
){
if
(
grid
[
i
][
j
]
==
0
)
{
...
...
@@ -53,35 +153,19 @@ bool findZero(int **grid, std::pair<int,int> &zeroIndex){
}
//Prints the board.
void
printBoard
(){
void
printBoard
(
const
int
(
&
grid
)[
9
][
9
]
){
for
(
int
i
=
0
;
i
<
9
;
++
i
){
for
(
int
j
=
0
;
j
<
9
;
++
j
){
std
::
cout
<<
grid
{
i
][
j
]
<<
" "
;
}
std
::
cout
<<
grid
[
i
][
j
]
<<
" "
;
}
std
::
cout
<<
std
::
endl
;
}
}
int
main
()
{
//Easy Grid:
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:
//Executes the algorithm:
void
solve
(
int
(
&
grid
)[
9
][
9
])
{
if
(
solveSudoku
(
grid
)
==
true
)
{
std
::
cout
<<
"Solved!"
<<
std
::
endl
;}
else
{
std
::
cout
<<
"Unsolvable :("
<<
std
::
endl
;}
printBoard
();
return
0
;
}
\ No newline at end of file
printBoard
(
grid
);
}
sudokuSolverPython.py
0 → 100644
View file @
306b5bd5
#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
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment