Я анализирую алгоритм bruteforce и задаю один вопрос.
var solveSudoku = function (grid, row, col) {
var field = findUnassignedLocation(grid, row, col);
row = field[0];
col = field[1];
if (row === -1) {
if (!newGameStatus) fillTheDom(grid);
return true;
}
for (var num = 1; num <= 9; num++) {
if (newGameStatus) {
num = Math.floor(Math.random() * 9) + 1;
}
if (isValid(grid, row, col, num)) {
console.log(row + ' ' + col)
grid[row][col] = num;
if (solveSudoku(grid, row, col)) {
return true;
}
console.log(row + ' ' + col)
grid[row][col] = 0;
}
}
return false;
}
var findUnassignedLocation = function (grid, row, col) {
var foundZero = false;
var location = [-1, -1];
while (!foundZero) {
if (row === 9) {
foundZero = true;
} else {
if (grid[row][col] === 0) {
location[0] = row;
location[1] = col;
foundZero = true;
} else {
if (col < 8) {
col++;
} else {
row++;
col = 0;
}
}
}
}
return location;
}
Если число не заполняется (каждый номер недействителен), рекурсивная функция возвращает false, правильно? Затем каким-то образом сбрасывает предыдущую заполненную ячейку. Как он возвращается к последней ячейке?
Каждый раз, когда функция вызывается, ее состояния сохраняются (до тех пор, пока все следующие состояния не сработают), и если они откажутся от процессора, вернется к последней ветке, у которой есть хотя бы одно, еще не прошедшее неудачу состояние, для перехода и продолжается до тех пор, пока решение не будет найдено или все не удается.
Я могу сделать gif, который бы объяснил это как можно проще, но я могу сделать это только после работы
Представьте себе рекурсию просто как форматирование.
solveSudoku(firstCell)
# Context : Global
On the first cell :
From 1 to 9 :
Is 1 valid ?
Yes.
If solveSudoku(nextCell):
# Context : We're in the loop of the first cell at iteration 1.
On the second cell :
From 1 to 9 :
Is 1 valid ?
No.
Is 2 valid ?
Yes.
If solveSudoku(nextCell):
# Context : We're in the loop of the second cell at iteration 2 which is in the loop of the first cell at iteration 1.
On the third cell :
From 1 to 9 :
Is 1 valid ?
No.
Is 2 valid ?
No.
Is 3 valid ?
No.
...
Is 9 valid ?
No.
Return false.
solveSudoku(nextCell = thirdCell) returned false, going on the loop. <<<<<<<<< This is "How does it goes back to the last cell?"
# Context : We're in the loop of the first cell at iteration 1.
Is 3 valid ?
Yes.
If solveSudoku(nextCell):
# Context : We're in the loop of the second cell at iteration 3 which is in the loop of the first cell at iteration 1.
On the third cell :
From 1 to 9 :
Is 1 valid ?
No.
Is 2 valid ?
Yes. <<<<<<< 2 is now valid and we can go on !
If solveSudoku(nextCell):
# Context : We're in the loop of the third cell at iteration 2 which is in the loop of the second cell at iteration 3 which is in the loop of the first cell at iteration 1.
On the fourth cell...
Как вы можете видеть, рекурсия идет глубже и может просто выйти на один уровень глубины, чтобы попробовать другой путь.