-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathSource.cpp
180 lines (161 loc) · 4.68 KB
/
Source.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <iostream>
#include <algorithm>
#include <vector>
#include <array>
using std::cout;
using std::endl;
#define DIM 9
#define BLANK 0
#define SPACE " "
#define LINE "|"
#define NEW_ROW "-------------------------------------"
#define GRID_FULL std::make_pair(9, 9)
// Prints the Soduko grid
void print_grid(int grid[DIM][DIM])
{
for (int i = 0; i < DIM; i++)
{
cout << SPACE << SPACE << SPACE << SPACE << endl;
cout << NEW_ROW << endl;
for (int j = 0; j < DIM; j++)
{
cout << SPACE;
if (BLANK == grid[i][j])
{
cout << SPACE;
}
else
{
cout << grid[i][j];
}
cout << SPACE;
cout << LINE;
}
}
cout << endl << NEW_ROW << endl << endl;;
}
// Returns a boolean which indicates whether any assigned entry
// in the specified row matches the given number.
bool used_in_row(int grid[DIM][DIM], int row, int num)
{
for (int col = 0; col < DIM; col++)
if (grid[row][col] == num)
{
return true;
}
return false;
}
// Returns a boolean which indicates whether any assigned entry
// in the specified column matches the given number.
bool used_in_col(int grid[DIM][DIM], int col, int num)
{
for (int row = 0; row < DIM; row++)
if (grid[row][col] == num)
{
return true;
}
return false;
}
// Returns a boolean which indicates whether any assigned entry
// within the specified 3x3 box matches the given number.
bool used_in_box(int grid[DIM][DIM], int box_start_rpw, int box_start_col, int num)
{
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
if (grid[row + box_start_rpw][col + box_start_col] == num)
{
return true;
}
return false;
}
// Returns a boolean which indicates whether it will be legal to assign
// num to the given row,col location.
bool is_safe(int grid[DIM][DIM], int row, int col, int num)
{
// Check if 'num' is not already placed in current row,
// current column and current 3x3 box
return !used_in_row(grid, row, num) &&
!used_in_col(grid, col, num) &&
!used_in_box(grid, row - row % 3, col - col % 3, num);
}
// Searches the grid to find an entry that is still unassigned. If
// found, the reference parameters row, col will be set the location
// that is unassigned, and true is returned. If no unassigned entries
// remain, false is returned.
std::pair<int, int> get_unassigned_location(int grid[DIM][DIM])
{
for (int row = 0; row < DIM; row++)
for (int col = 0; col < DIM; col++)
if (grid[row][col] == BLANK)
{
return std::make_pair(row, col);
}
return GRID_FULL;
}
// Takes a partially filled-in grid and attempts to assign values to
// all unassigned locations in such a way to meet the requirements
// for Sudoku solution (non-duplication across rows, columns, and boxes)
bool solve_soduko(int grid[DIM][DIM])
{
// If the Soduko grid has been filled, we are done
if (GRID_FULL == get_unassigned_location(grid))
{
return true;
}
// Get an unassigned Soduko grid location
std::pair<int, int> row_and_col = get_unassigned_location(grid);
int row = row_and_col.first;
int col = row_and_col.second;
// Consider digits 1 to 9
for (int num = 1; num <= 9; num++)
{
// If placing the current number in the current
// unassigned location is valid, go ahead
if (is_safe(grid, row, col, num))
{
// Make tentative assignment
grid[row][col] = num;
// Do the same thing again recursively. If we go
// through all of the recursions, and in the end
// return true, then all of our number placements
// on the Soduko grid are valid and we have fully
// solved it
if (solve_soduko(grid))
{
return true;
}
// As we were not able to validly go through all
// of the recursions, we must have an invalid number
// placement somewhere. Lets go back and try a
// different number for this particular unassigned location
grid[row][col] = BLANK;
}
}
// If we have gone through all possible numbers for the current unassigned
// location, then we probably assigned a bad number early. Lets backtrack
// and try a different number for the previous unassigned locations.
return false;
}
int main()
{
cout << "********************************\n\n\tSudoku Solver\n\n********************************" << endl << endl;
int grid[DIM][DIM] = { { 0, 9, 0, 0, 0, 0, 8, 5, 3 },
{ 0, 0, 0, 8, 0, 0, 0, 0, 4 },
{ 0, 0, 8, 2, 0, 3, 0, 6, 9 },
{ 5, 7, 4, 0, 0, 2, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 0, 6, 3, 7 },
{ 9, 4, 0, 1, 0, 8, 5, 0, 0 },
{ 7, 0, 0, 0, 0, 6, 0, 0, 0 },
{ 6, 8, 2, 0, 0, 0, 0, 9, 0 } };
print_grid(grid);
if (true == solve_soduko(grid))
{
print_grid(grid);
}
else
{
cout << "No solution exists for the given Soduko" << endl << endl;
}
return 0;
}