I'm looking to implement a very simple algorithm that uses brute-force back-tracking to solve Sudoku grids. The problem I'm facing is that in my implementation I included two instance variables for a Sudoku
class called row
and col
, which correspond to the row and column of an empty cell in a two dimensional array that represents the Sudoku grid.
When my solve()
method executes it first checks to see if there aren't any empty cells, in which case the puzzle is already complete. Otherwise, that same method assigns the row and column of an empty cell to the instance variables row
and col
of the Sudoku
object that contains the grid. Afterwards, the for loop verifies which number can be placed in that empty cell through a method call isSafe(int n)
(This method checks to see if the constraints of the puzzle are being met, I can guarantee that it functions perfectly). So, the isSafe()
method places a number in the empty cell and then makes a recursive call to the solve()
method again on the Sudoku
object.
If we hit a constraint that can't be met, then we reassign a 0
to the last row
and col
that was filled. This is where the problem is found! Since the program is constantly updating the row
and col
variables then the old instances are lost with each recursive call. I have been trying to figure out how to store this values so the program can undo actions when it back-tracks. I thought about pushing each col
and row
to a stack but I'm really not sure where to go.
Can somebody tell me what would be a simple way to approach this problem? I'm not including the entire class, if you think it'd be helpful let me know and I'll post it.
class Sudoku {
int SIZE, N, row, col;
int Grid[][];
public boolean solve() {
if (!this.findNextZero()) return true;
for (int num = 1; num <= 9; num++) {
if (isSafe(num)) {
this.Grid[this.row][this.col] = num;
if (this.solve()) return true;
this.Grid[this.row][this.col] = 0;
// this.Grid[oldRow][oldCol] = 0;
}
}
return false;
}
public boolean findNextZero() {
for (int i = 0; i < this.N; i++) {
for (int j = 0; j < this.N; j++) {
if (this.Grid[i][j] == 0) {
this.row = i;
this.col = j;
return true;
}
}
}
return false;
}
public boolean isSafe(int num) {
return !this.usedInRow(num)
&& !this.usedInColumn(num)
&& !this.usedInBox(num);
}
If I were to implement a stack, does the following make sense? After the findNextZero()
operations push the row
and col
integers onto the stack. Keep doing this and then modify the following line of code
this.Grid[this.row][this.col] = 0;
to something like
this.Grid[s.pop][s.pop] = 0;
Is this a reasonable approach?