JavaScript Судоку решатель. Откуда взялся предыдущий номер?

1

Я анализирую алгоритм 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, правильно? Затем каким-то образом сбрасывает предыдущую заполненную ячейку. Как он возвращается к последней ячейке?

Теги:
sudoku
solver

2 ответа

0

Каждый раз, когда функция вызывается, ее состояния сохраняются (до тех пор, пока все следующие состояния не сработают), и если они откажутся от процессора, вернется к последней ветке, у которой есть хотя бы одно, еще не прошедшее неудачу состояние, для перехода и продолжается до тех пор, пока решение не будет найдено или все не удается.

Я могу сделать gif, который бы объяснил это как можно проще, но я могу сделать это только после работы

0

Представьте себе рекурсию просто как форматирование.

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...

Как вы можете видеть, рекурсия идет глубже и может просто выйти на один уровень глубины, чтобы попробовать другой путь.

  • 0
    Так как в JavaScript? Каждый раз, когда вызывается функция, создается контент исполнения? Каждый исполняемый контент имеет свои переменные и состояния?
  • 0
    Да, конечно. Каждый из этих вызовов функций независим и имеет свои собственные переменные, он получает переданные параметры и все!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню