generated from Trianta/cpp-unity-template
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
dd3c92f6f7 | ||
|
6255b786a1 |
133
src/sudoku.cpp
133
src/sudoku.cpp
@ -25,13 +25,19 @@ void Sudoku::FillBoard(std::string filePath) {
|
|||||||
|
|
||||||
// Base global call for solving
|
// Base global call for solving
|
||||||
void Sudoku::Solve(void) {
|
void Sudoku::Solve(void) {
|
||||||
_Solve();
|
if (!_Solve()) { std::cerr << "No solution found" << std::endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sudoku::IsBoardSolved(void) {
|
bool Sudoku::IsBoardSolved(void) {
|
||||||
int column, row;
|
int row, column;
|
||||||
if (!FindEmptyCell(&column, &row)) { return true; }
|
for (row = 0; row < 9; row += 3) {
|
||||||
return false;
|
for (column = 0; column < 9; column += 3) {
|
||||||
|
if (!GetUnusedRow(row).empty()) { return false; }
|
||||||
|
if (!GetUnusedColumn(column).empty()) { return false; }
|
||||||
|
if (!GetUnusedSubgrid(row, column).empty()) { return false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sudoku::Print(void) {
|
void Sudoku::Print(void) {
|
||||||
@ -57,12 +63,19 @@ void Sudoku::RawPrint(void) {
|
|||||||
|
|
||||||
// Recursive call for solving
|
// Recursive call for solving
|
||||||
bool Sudoku::_Solve(void) {
|
bool Sudoku::_Solve(void) {
|
||||||
int column, row;
|
int row, column;
|
||||||
if (!FindEmptyCell(&column, &row)) { return true; }
|
if (!FindEmptyCell(row, column)) {
|
||||||
for (int i : GetUnusedRow(row)) {
|
if (IsBoardSolved()) { return true; }
|
||||||
for (int j : GetUnusedColumn(column)) {
|
return false;
|
||||||
for (int k : GetUnusedSubgrid(column, row)) {
|
}
|
||||||
if (i == j == k) {
|
std::vector<int> rowPossiblities, columnPossibilities, subgridPossibilities;
|
||||||
|
rowPossiblities = GetUnusedRow(row);
|
||||||
|
columnPossibilities = GetUnusedColumn(column);
|
||||||
|
subgridPossibilities = GetUnusedSubgrid(row, column);
|
||||||
|
for (int i : rowPossiblities) {
|
||||||
|
for (int j : columnPossibilities) {
|
||||||
|
for (int k : subgridPossibilities) {
|
||||||
|
if (i == j && j == k) {
|
||||||
board[row][column] = i;
|
board[row][column] = i;
|
||||||
if (_Solve()) { return true; }
|
if (_Solve()) { return true; }
|
||||||
board[row][column] = 0;
|
board[row][column] = 0;
|
||||||
@ -70,83 +83,63 @@ bool Sudoku::_Solve(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fills column and row of an empty cell and returns true
|
// Fills column and row of an empty cell and returns true
|
||||||
// If no empty cell is found, return false
|
// If no empty cell is found, return false
|
||||||
bool Sudoku::FindEmptyCell(int* column, int* row) {
|
bool Sudoku::FindEmptyCell(int& row, int& column) {
|
||||||
for (*row = 0; *row < 9; ++(*row)) {
|
for (row = 0; row < 9; ++(row)) {
|
||||||
for (*column = 0; *column < 9; ++(*column)) {
|
for (column = 0; column < 9; ++(column)) {
|
||||||
if (board[*row][*column] == 0) { return true; }
|
if (board[row][column] == 0) { return true; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sudoku::IsValidPlacement(int column, int row, int box) {
|
// Returns vector of unused numbers in row
|
||||||
// Check column and row
|
std::vector<int> Sudoku::GetUnusedRow(const int& row) {
|
||||||
for (int i = 0; i < 9; ++i) {
|
std::vector<int> leftOver{0,1,2,3,4,5,6,7,8,9};
|
||||||
if (board[row][i] == box || board[i][column] == box) {
|
int* box;
|
||||||
return false;
|
for (int i = 0; i < 9; i++) {
|
||||||
}
|
box = &board[row][i];
|
||||||
|
if (leftOver[*box] == *box) { leftOver[*box] = 0; }
|
||||||
}
|
}
|
||||||
|
TrimPossiblities(leftOver);
|
||||||
// Check subgrid
|
return leftOver;
|
||||||
int startRow = row - row % 3;
|
}
|
||||||
int startColumn = column - column % 3;
|
|
||||||
|
// Returns vector of unused numbers in column
|
||||||
|
std::vector<int> Sudoku::GetUnusedColumn(const int& column) {
|
||||||
|
std::vector<int> leftOver{0,1,2,3,4,5,6,7,8,9};
|
||||||
|
int* box;
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
box = &board[i][column];
|
||||||
|
if (leftOver[*box] == *box) { leftOver[*box] = 0; }
|
||||||
|
}
|
||||||
|
TrimPossiblities(leftOver);
|
||||||
|
return leftOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns vector of unused numbers in subgrid
|
||||||
|
std::vector<int> Sudoku::GetUnusedSubgrid(const int& row, const int& column) {
|
||||||
|
std::vector<int> leftOver{0,1,2,3,4,5,6,7,8,9};
|
||||||
|
int* box;
|
||||||
|
int startRow = row - (row % 3);
|
||||||
|
int startColumn = column - (column % 3);
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
if (board[startRow + i][startColumn + j] == box) { return false; }
|
box = &board[startRow + i][startColumn + j];
|
||||||
|
if (leftOver[*box] == *box) { leftOver[*box] = 0; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
TrimPossiblities(leftOver);
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> Sudoku::GetUnusedRow(int row) {
|
|
||||||
std::vector<int> leftOver{0,1,2,3,4,5,6,7,8,9};
|
|
||||||
int box;
|
|
||||||
for (int i = 0; i < 9; i++) {
|
|
||||||
box = board[row][i];
|
|
||||||
if (leftOver[box] == box) { leftOver[box] = 0; }
|
|
||||||
}
|
|
||||||
for (auto it = leftOver.begin(); it != leftOver.end();) {
|
|
||||||
if (*it == 0) { it = leftOver.erase(it); }
|
|
||||||
else { ++it; }
|
|
||||||
}
|
|
||||||
return leftOver;
|
return leftOver;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> Sudoku::GetUnusedColumn(int column) {
|
void TrimPossiblities(std::vector<int>& possibilities) {
|
||||||
std::vector<int> leftOver{0,1,2,3,4,5,6,7,8,9};
|
for (auto it = possibilities.begin(); it != possibilities.end();) {
|
||||||
int box;
|
if (*it == 0) { it = possibilities.erase(it); }
|
||||||
for (int i = 0; i < 9; i++) {
|
|
||||||
box = board[i][column];
|
|
||||||
if (leftOver[box] == box) { leftOver[box] = 0; }
|
|
||||||
}
|
|
||||||
for (auto it = leftOver.begin(); it != leftOver.end();) {
|
|
||||||
if (*it == 0) { it = leftOver.erase(it); }
|
|
||||||
else { ++it; }
|
else { ++it; }
|
||||||
}
|
}
|
||||||
return leftOver;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> Sudoku::GetUnusedSubgrid(int column, int row) {
|
|
||||||
std::vector<int> leftOver{0,1,2,3,4,5,6,7,8,9};
|
|
||||||
int box;
|
|
||||||
int startRow = row - row % 3;
|
|
||||||
int startColumn = column - column % 3;
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
for (int j = 0; j < 3; ++j) {
|
|
||||||
box = board[row][column];
|
|
||||||
if (board[startRow + i][startColumn + j] == box) {
|
|
||||||
leftOver[box] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto it = leftOver.begin(); it != leftOver.end();) {
|
|
||||||
if (*it == 0) { it = leftOver.erase(it); }
|
|
||||||
else { ++it; }
|
|
||||||
}
|
|
||||||
return leftOver;
|
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,12 @@ public:
|
|||||||
void RawPrint(void);
|
void RawPrint(void);
|
||||||
private:
|
private:
|
||||||
bool _Solve(void);
|
bool _Solve(void);
|
||||||
bool FindEmptyCell(int* column, int* row);
|
bool FindEmptyCell(int& row, int& column);
|
||||||
bool IsValidPlacement(int column, int row, int box);
|
std::vector<int> GetUnusedRow(const int& row);
|
||||||
std::vector<int> GetUnusedRow(int row);
|
std::vector<int> GetUnusedColumn(const int& column);
|
||||||
std::vector<int> GetUnusedColumn(int column);
|
std::vector<int> GetUnusedSubgrid(const int& row, const int& column);
|
||||||
std::vector<int> GetUnusedSubgrid(int column, int row);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void TrimPossiblities(std::vector<int>& possibilities);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,6 +9,6 @@ int main(int argc, char* argv[]) {
|
|||||||
Sudoku newGame;
|
Sudoku newGame;
|
||||||
newGame.FillBoard(argv[1]);
|
newGame.FillBoard(argv[1]);
|
||||||
newGame.Solve();
|
newGame.Solve();
|
||||||
newGame.RawPrint();
|
newGame.Print();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user