-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolver.cpp
146 lines (135 loc) · 4.9 KB
/
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
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
#include<tuple>
#include<iostream>
#include<string>
using namespace std;
// A struct to return coordinates from FindEmptyCell
struct Location {
int x;
int y;
};
// Prints a sudoku puzzle with a grid for readability.
void PrintPuzzle(int sudoku[9][9]) {
for (int i=0; i<9; i++) {
if (i % 3 == 0 && i != 0) {
cout << "-----------------\n";
}
for (int j=0; j<9; j++) {
if (j % 3 == 0 && j != 0) {
cout << "| ";
}
cout << sudoku[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
// Gets the puzzle to be solved via a command line input from the user.
void InputPuzzle(int sudoku[9][9]) {
cout << "\nEnter the Sudoku puzzle you would like to solve.\nInput the puzzle as a single line of numbers from left to right and top to bottom.\n - Use 0 to indicate empty cells, and seperate all numbers by a single space.\n";
cout << " - Upon submission, the puzzle will be printed below for confirmation that it appears as intended:\n\n";
for (int i=0; i<9; i++) {
for (int j=0; j<9; j++) {
cin >> sudoku[i][j];
}
}
int is_correct = 0;
// ensures the user input their puzzle as intended
while (is_correct == 0) {
cout << "\n" << "You have entered:\n\n";
PrintPuzzle(sudoku);
cout << "Does the puzzle appear as intended?\n\nIf it appears correctly, enter 1, and the puzzle will be solved in an instant.\nIf it does not appear correctly, enter 0 to make an edit.\n";
cout << "If the puzzle you have entered has no valid solution, the program will quit.\n";
cin >> is_correct;
if (is_correct == 1) {
cout << "\n";
break;
}
int x, y; cout << "Enter the coordinates of the cell to be changed seperated by a space on a 9X9 grid indexed at 0.\n";
cin >> x >> y;
cout << "Input the new value for this cell:\n";
cin >> sudoku[x][y];
}
}
// Returns the coordinates (as a struct called "Location") of an empty cell. Returns Location {9, 9} if all cells are full.
Location FindEmptyCell(int sudoku[9][9]) {
for (int i=0; i<9; i++) {
for (int j=0; j<9; j++) {
if (sudoku[i][j] == 0) {
Location coordinates {i, j};
return coordinates;
}
}
}
return Location {9, 9};
}
// For the current number being guessed at the current cell, checks whether this is valid for the row.
bool CheckRow (int sudoku[9][9], int num_guess, int x, int y) {
for (int i=0; i<9; i++) {
if (sudoku[x][i] == num_guess && i != y) {
return false;
}
}
return true;
}
// The same for a column --
bool CheckCol (int sudoku[9][9], int num_guess, int x, int y) {
for (int i=0; i<9; i++) {
if (sudoku[i][y] == num_guess && i != x) {
return false;
}
}
return true;
}
// Checks whether the current guess appears again inside the "box" our current cell is in.
bool CheckBox (int sudoku[9][9], int num_guess, int x, int y) {
int x_box = x / 3;
int y_box = y / 3;
for (int i = x_box * 3; i < x_box * 3 + 3; i++) {
for (int j = y_box * 3; j < y_box * 3 + 3; j++) {
if (sudoku[i][j] == num_guess && (i != x && j != y)) {
return false;
}
}
}
return true;
}
// Checks row and col and box for a repeat of the guess. Returns false when invalid.
bool ValidGuess (int sudoku[9][9], int num_guess, int x, int y) {
return (CheckRow(sudoku, num_guess, x, y) && CheckCol(sudoku, num_guess, x, y) && CheckBox(sudoku, num_guess, x, y));
}
// Guesses numbers at empty cells. Recursively calls itself until base case is reached: FindEmptyCell returns 9, 9.
bool Solver (int sudoku[9][9]) {
Location coordinates = FindEmptyCell(sudoku);
int x = coordinates.x;
int y = coordinates.y;
if (x == 9 && y == 9) {
return true;
}
for (int guess = 1; guess < 10; guess++) {
if (ValidGuess(sudoku, guess, x, y) == true) {
sudoku[x][y] = guess;
if (Solver(sudoku) == true) {
return true;
}
// Backtracks here if the sudoku is not solved, deleting the value at x, y.
sudoku[x][y] = 0;
}
}
return false;
}
// Main. Calls for input. Uses this puzzle in Solver. Prints the solved sudoku once Solver returns true.
int main () {
int done = 0;
int sudoku[9][9];
InputPuzzle(sudoku);
if (Solver(sudoku) == true) {
cout << "Ta-da! Your puzzle's solution is as follows:\n\n";
PrintPuzzle(sudoku);
int done;
cout << "Press CTRL + C to exit.\n";
cin >> done;
if (done == 1) {
return true;
}
}
}