samedi 26 juillet 2014

Java - détection de boucle infinie ? -Débordement de pile


I'm working on a Sudoku solver program. The idea is that the user inputs the Sudoku puzzle and the program solves it for them.


The program works fine when entering any normal puzzle. However, there are some puzzles that are impossible to solve. Here is one example that I entered: http://i.imgur.com/5L8pF8Q.png


The input is perfectly legal, but top right square cannot be filled in since all numbers 1-9 have been used in that row and column. If I hit "Solve", my program freezes as it enters an infinite loop.


So my question here is, how can I prevent this from happening?


I tried implementing the "boolean flag" approach, but on second thought I realized that it's probably not feasible.


Here is my solver method:


public boolean solve(int i, int j) {
for (int a = 0; a < 9; a++) {
for (int b = 0; b < 9; b++) {
if (sudokuArray[a][b] == 0) {
for (int k = 1; k <= 9; k++) {
sudokuArray[a][b] = k;
if (checkNumber(a, b, k) && solve(a, b)) {
return true;
}else {
sudokuArray[a][b] = 0;
}
}
return false;
}
}
}
return true;
}

The checkNumber() method checks if number k can be legally inserted in row a, column b and returns true/false accordingly.


Ideas? Tips?


Thanks.


PS: Added checkNumber() as requested:


public boolean checkNumber(int i, int j, int num) {
for (int a = 0; a < 9; a++) {
if (a != i) {
if (sudokuArray[a][j] == num) {
return false;
}
}
if (a != j) {
if (sudokuArray[i][a] == num) {
return false;
}
}
}
for (int a = (i / 3) * 3; a < (i / 3) * 3 + 3; a++) {
for (int b = (j / 3) * 3; b < (j / 3) * 3 + 3; b++) {
if ((a != i) && (b != j)) {
if (sudokuArray[a][b] == num) {
return false;
}
}
}
}
return true;
}


I'm working on a Sudoku solver program. The idea is that the user inputs the Sudoku puzzle and the program solves it for them.


The program works fine when entering any normal puzzle. However, there are some puzzles that are impossible to solve. Here is one example that I entered: http://i.imgur.com/5L8pF8Q.png


The input is perfectly legal, but top right square cannot be filled in since all numbers 1-9 have been used in that row and column. If I hit "Solve", my program freezes as it enters an infinite loop.


So my question here is, how can I prevent this from happening?


I tried implementing the "boolean flag" approach, but on second thought I realized that it's probably not feasible.


Here is my solver method:


public boolean solve(int i, int j) {
for (int a = 0; a < 9; a++) {
for (int b = 0; b < 9; b++) {
if (sudokuArray[a][b] == 0) {
for (int k = 1; k <= 9; k++) {
sudokuArray[a][b] = k;
if (checkNumber(a, b, k) && solve(a, b)) {
return true;
}else {
sudokuArray[a][b] = 0;
}
}
return false;
}
}
}
return true;
}

The checkNumber() method checks if number k can be legally inserted in row a, column b and returns true/false accordingly.


Ideas? Tips?


Thanks.


PS: Added checkNumber() as requested:


public boolean checkNumber(int i, int j, int num) {
for (int a = 0; a < 9; a++) {
if (a != i) {
if (sudokuArray[a][j] == num) {
return false;
}
}
if (a != j) {
if (sudokuArray[i][a] == num) {
return false;
}
}
}
for (int a = (i / 3) * 3; a < (i / 3) * 3 + 3; a++) {
for (int b = (j / 3) * 3; b < (j / 3) * 3 + 3; b++) {
if ((a != i) && (b != j)) {
if (sudokuArray[a][b] == num) {
return false;
}
}
}
}
return true;
}

0 commentaires:

Enregistrer un commentaire