-
-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathsudoku_solver.cpp
110 lines (101 loc) · 3.17 KB
/
sudoku_solver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
* @file sudoku_solve.cpp
* @author your name ([email protected])
* sudoku disebut dengan number placement game.
* informasi lebih lanjut tentang sudoku
* https://en.wikipedia.org/wiki/Sudoku
*/
#include <array> /// for assert
#include <iostream> /// for IO operations
/**
* @namespace backtracking
* @brief Backtracking algorithms
*/
namespace backtracking {
namespace sudoku_solver {
template <size_t V>
bool isPossible(const std::array<std::array<int, V>, V> &mat, int i, int j,
int no, int n) {
for (int x = 0; x < n; x++) {
if (mat[x][j] == no || mat[i][x] == no) {
return false;
}
}
int sx = (i / 3) * 3;
int sy = (j / 3) * 3;
for (int x = sx; x < sx + 3; x++) {
for (int y = sy; y < sy + 3; y++) {
if (mat[x][y] == no) {
return false;
}
}
}
return true;
}
template <size_t V>
void printMat(const std::array<std::array<int, V>, V> &mat,
const std::array<std::array<int, V>, V> &starting_mat, int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (starting_mat[i][j] != mat[i][j]) {
std::cout << "\033[93m" << mat[i][j] << "\033[0m"
<< " ";
} else {
std::cout << mat[i][j] << " ";
}
if ((j + 1) % 3 == 0) {
std::cout << '\t';
}
}
if ((i + 1) % 3 == 0) {
std::cout << std::endl;
}
std::cout << std::endl;
}
}
template <size_t V>
bool solveSudoku(std::array<std::array<int, V>, V> &mat,
const std::array<std::array<int, V>, V> &starting_mat, int i,
int j) {
if (i == 9) {
printMat<V>(mat, starting_mat, 9);
return true;
}
if (j == 9) {
return solveSudoku<V>(mat, starting_mat, i + 1, 0);
}
if (mat[i][j] != 0) {
return solveSudoku<V>(mat, starting_mat, i, j + 1);
}
for (int no = 1; no <= 9; no++) {
if (isPossible<V>(mat, i, j, no, 9)) {
mat[i][j] = no;
bool solution_found = solveSudoku<V>(mat, starting_mat, i, j + 1);
if (solution_found) {
return true;
}
}
}
mat[i][j] = 0;
return false;
}
} // namespace sudoku_solver
} // namespace backtracking
int main() {
const int V = 9;
std::array<std::array<int, V>, V> mat = {
std::array<int, V>{5, 3, 0, 0, 7, 0, 0, 0, 0},
std::array<int, V>{6, 0, 0, 1, 9, 5, 0, 0, 0},
std::array<int, V>{0, 9, 8, 0, 0, 0, 0, 6, 0},
std::array<int, V>{8, 0, 0, 0, 6, 0, 0, 0, 3},
std::array<int, V>{4, 0, 0, 8, 0, 3, 0, 0, 1},
std::array<int, V>{7, 0, 0, 0, 2, 0, 0, 0, 6},
std::array<int, V>{0, 6, 0, 0, 0, 0, 2, 8, 0},
std::array<int, V>{0, 0, 0, 4, 1, 9, 0, 0, 5},
std::array<int, V>{0, 0, 0, 0, 8, 0, 0, 7, 9}};
backtracking::sudoku_solver::printMat<V>(mat, mat, 9);
std::cout << "Solution " << std::endl;
std::array<std::array<int, V>, V> starting_mat = mat;
backtracking::sudoku_solver::solveSudoku<V>(mat, starting_mat, 0, 0);
return 0;
}