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
|
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <stack>
using namespace std;
/* FUNCTION PROTOTYPES: */
bool solveSudoku(vector< vector<int> > &board);
bool findRemainingSlots(vector< vector<int> > &board, int &row, int &column);
bool checkingRow(vector< vector<int> > &board, int row, int value);
bool checkingColumn(vector< vector<int> > &board, int column, int value);
bool checkingBox(vector< vector<int> > &board, int box_row, int box_column, int value);
bool isLegal(vector< vector<int> > &board, int row, int column, int value);
stack<int> solvedSudokuNumbers; // Stack holding the found values of the solved sudoku board
vector< vector<int> > board;
int N;
int root;
/* MAIN FUNCTION */
int main(int argc, char** argv){
/* For error in inputs */
if ((argc == 1) || (argc%3 != 2)){
cout << "Please enter either N, or N followed by multiples of (x,y,value)\n";
return 1; // 1 is returned because the number of arguments is incorrect.
}
int N = atoi(argv[1]); // The first input is N, which chooses an NxN sudoku grid
vector< vector<int> > board(N, vector<int>(N, 0)); // Initializing all values of the sudoku board to 0
int root = static_cast<int> (sqrt(N)); // 'root' is the square root of N's nearest integer
if(root != sqrt(N)){ // If the square root of N is not exactly that integer, a sudoku grid cannot be constructed
cout << "Your input cannot create a valid Sudoku board";
return 2; // 2, returned, means a sudoku grid was not able to be created.
}
solveSudoku(board);
for(int row = 0; row < N; row++){
for(int column = 0; column < N; column++){
cout << board[row][column] << " ";
}
cout << '\n';
}
return 0;
}
bool solveSudoku(vector< vector<int> > &board){ // Function solveSudoku() takes in a vector of integers representing the board.
int row = 1;
int column = 1;
if(!(findRemainingSlots(board, row, column))){ // If there are no 0 values left on the sudoku board,
return true; // All the values have been assigned to their appropriate slots!
}
for(int value = 1; value <= N; value++){ // Iterating through each possible value!
if(isLegal(board, row, column, value)){ // If the value is legal for that sudoku board spot,
board[row][column] = value; // we assign the value to that location in the board vector
solvedSudokuNumbers.push(value); // Putting that number on the top of the solved sudoku spot!
if(solveSudoku(board)){ // If solveSudoku returns true for every value in the vector board,
return true; // then we can finally return true. This is a recursive loop so that solveSudoku will keep calling itself until the value for the whole board is true
}
}
}
solvedSudokuNumbers.pop(); // If solveSudoku is not true, we get rid of the last number in the stack.
return false; // The code reaches here if the solveSudoku is not true yet. This triggers the backtracking! So it will go back and reassign numbers to the previous values.
}
bool findRemainingSlots(vector< vector<int> > &board, int &row, int &column){
for(row = 0; row < N; row++){ // Double for loop iterates through the sudoku board vector
for(column = 0; column < N; column++){
if(board[row][column] == 0){ // If the spot on the board has a value of 0, it doesn't have a value assigned to it yet!
return true; // Return true because it's a remaining slot
}
}
}
return false; // Return false because there are no remaining slots
}
bool checkingRow(vector< vector<int> > &board, int row, int value){
for(int column = 0; column < N; column++){ // Iterating through the column...
if(board[row][column] == value){ // If the value at the column is equal to the current value,
return true; // we return true because the value is found and used in the row already
}
}
return false; // Returns false because the value is not anywhere else in the row
}
bool checkingColumn(vector< vector<int> > &board, int column, int value){
for(int row = 0; row < N; row++){ // Iterating through the row...
if(board[row][column] == value){ // If the value at the row is equal to the current value,
return true; // we return true because the value is found and used in the column already.
}
}
return false; // Returns false because the value is not anywhere else in the column
}
bool checkingBox(vector< vector<int> > &board, int box_row, int box_column, int value){
for(int row = 0; row < sqrt(N); row++){ // Double for loop iterates through the small boxes of the sudoku board
for(int column = 0; column < sqrt(N); column++){
if(board[row+box_row][column+box_column] == value){ // If the value is matched to any of the existing values in the small box of the sudoku board,
return true; // we return true because the value is found and used in the small box already.
}
}
}
return false; // Returns false because the value is not anywhere else in the small box
}
bool isLegal(vector< vector<int> > &board, int row, int column, int value){
bool state = (!checkingRow(board, row, value) && !checkingColumn(board, row, value) && !checkingBox(board, row-row%(root), column-column%(root), value)); // If the value has not been used in the corresponding row, column, and box,
return state; // we return true. If not, we return false.
}
|