I would like to write function which will count the number of possible solutions there are for a given Sudoku board.
In addition, I would like it to be implemented as an iterative solution using a stack.
I found this recursive solution, which is implemented in Java, and I've written it in C (it is first called with countSolutionsRec(board, 0, 0, 0)
, where board is 2D array of integers which represents the Sudoku board game):
int countSolutionsRec(int board[9][9], int i, int j, int counter) {
int value;
if (i == 9) {
i = 0;
if (++j == 9){
return 1+counter;
}
}
if (board[i][j] != 0){
return countSolutionsRec(board, i+1, j, counter);
}
for (value = 1; value <= 9; ++value) {
if (validCheck(board, j, i, value)){ //This function checks if the value is a legal value to place in board[i][j] according to sudoku rules
board[i][j]= value;
counter = countSolutionsRec(board, i+1, j, counter);
}
}
board[i][j] = 0;
return counter;
}
Then, I've tried to follow this guide to convert the above code to an iterative implementation using a stack, and this is what I came up with:
int countSolutions(int board[9][9]) {
int returnValue, value;
SnapShotStruct newSnapshot;
StackNode* snapshotStack;
SnapShotStruct currentSnapshot;
currentSnapshot.i = 0;
currentSnapshot.j = 0;
currentSnapshot.counter = 0;
push(&snapshotStack, currentSnapshot);
while (!empty(snapshotStack)) {
currentSnapshot=top(snapshotStack);
pop(&snapshotStack);
if (currentSnapshot.i == 9){
currentSnapshot.i = 0;
if (++currentSnapshot.j == 9) {
returnValue = currentSnapshot.counter + 1;
continue;
}
}
if (board[currentSnapshot.i][currentSnapshot.j] != 0) {
newSnapshot.i = currentSnapshot.i + 1;
newSnapshot.j = currentSnapshot.j;
newSnapshot.counter = currentSnapshot.counter;
push(&snapshotStack, newSnapshot);
continue;
}
for (value = 1; value <= 9; ++value) {
if (validCheck(board, currentSnapshot.j, currentSnapshot.i, value)){
board[currentSnapshot.i][currentSnapshot.j] = value;
newSnapshot.i = currentSnapshot.i + 1;
newSnapshot.j = currentSnapshot.j;
newSnapshot.counter = returnValue;
push(&snapshotStack, newSnapshot);
continue;
}
}
board[currentSnapshot.i][currentSnapshot.j] = 0;
}
return returnValue;
}
My stack implementation:
typedef struct SnapShotStruct {
int i;
int j;
int counter;
int stage;
} SnapShotStruct;
typedef struct StackNode {
struct SnapShotStruct snapshot;
struct StackNode* next;
} StackNode;
StackNode* newNode(SnapShotStruct snapshot) {
StackNode* stackNode = (StackNode*) malloc(sizeof(StackNode));
stackNode->snapshot.i = snapshot.i;
stackNode->snapshot.j = snapshot.j;
stackNode->snapshot.counter = snapshot.counter;
stackNode->snapshot.stage = snapshot.stage;
stackNode->next = NULL;
return stackNode;
}
int empty(StackNode *root) {
return !root;
}
void push(StackNode** root, SnapShotStruct snapshot) {
StackNode* stackNode = newNode(snapshot);
stackNode->next = *root;
*root = stackNode;
}
SnapShotStruct pop(StackNode** root) {
SnapShotStruct popped;
StackNode* temp = *root;
if (empty(*root))
return popped;
*root = (*root)->next;
popped = temp->snapshot;
free(temp);
return popped;
}
SnapShotStruct top(StackNode* root) {
SnapShotStruct snapshot;
if (empty(root))
return snapshot;
snapshot = root->snapshot;
return snapshot;
}
The problem is that I get wrong results from the iterative implementation.
I think the issue is the way I've converted the following line:
counter = countSolutionsRec(board, i+1, j, counter);
But I'm not sure how to fix it and get my iterative implementation to return the correct results.
Any help is appreciated.