Почему мой решатель судоку возвращает пустую сетку судоку?

Я пытаюсь создать свой собственный решатель судоку в Python, но он возвращает пустую сетку судоку.

Я попытался визуализировать свой код на pythontutor, чтобы увидеть, что не так, но числа в первой строке правильные.

Поэтому я не знаю, почему он возвращает пустую сетку. Под пустой сеткой я подразумеваю, что она возвращает ту же самую сетку, что и в начале. 0 не заменяются числами.

Вот мой код:

board = [
        [7, 8, 0, 4, 0, 0, 1, 2, 0],
        [6, 0, 0, 0, 7, 5, 0, 0, 9],
        [0, 0, 0, 6, 0, 1, 0, 7, 8],
        [0, 0, 7, 0, 4, 0, 2, 6, 0],
        [0, 0, 1, 0, 5, 0, 9, 3, 0],
        [9, 0, 4, 0, 6, 0, 0, 0, 5],
        [0, 7, 0, 3, 0, 0, 0, 1, 2],
        [1, 2, 0, 0, 0, 7, 4, 0, 0],
        [0, 4, 9, 2, 0, 6, 0, 0, 7]
    ]

def valid(row, col, number):
    global board
    for i in range(0,9):
        if board[row][i]==number:
            return False
    
    for i in range(0,9):
        if board[i][col]==number:
            return False
    
    col_start = (col//3)*3
    row_start = (row//3)*3 

    for r in range(0, 3):
        for c in range(0, 3):
            if board[row_start+r][col_start+c]==number:
                return False
    return True

def solve_sudoku():
    global board
    for row in range(9):
        for col in range(9):
            if board[row][col]==0:
                for number in range(1,10):
                    if valid(row, col, number):
                        board[row][col] = number
                        solve_sudoku()
                        board[row][col] = 0
                return False


print(board)
solve_sudoku()
print(board)

person CLSigma    schedule 08.01.2021    source источник
comment
что такое пустая сетка?   -  person juanpa.arrivillaga    schedule 08.01.2021
comment
Под пустой сеткой я подразумеваю, что все 0 не заменяются числами. Я собираюсь отредактировать, чтобы быть более точным   -  person CLSigma    schedule 08.01.2021
comment
Ммм, ну, на самом деле я ничего не знаю о содоку, но ваша функция solve_sudoku проверяет, равно ли число нулю, if board[row][col] == 0: затем вы меняете его на число: board[row][col] = number но затем сразу после этого вы меняете его назад к нулю: board[row][col] = 0   -  person juanpa.arrivillaga    schedule 08.01.2021
comment
if board[row][col] == 0: для возврата. Это означает, что если в случае нет правильных чисел, он вернется к предыдущему делу. Я имею в виду, может быть, я ошибаюсь, потому что я все еще пытаюсь понять рекурсивность и возврат. Но я точно знаю, что первая строка успешно завершена, и я не знаю, почему она возвращает входную сетку.   -  person CLSigma    schedule 08.01.2021
comment
Я уже объяснил вам, что любое изменение, которое вы вносите в глобальный объект board, будет отменено. Подумай об этом. Вы говорите ему измениться на какое-то число, а затем сразу же говорите ему вернуться к 0. Вместо этого не полагайтесь на изменение глобального объекта платы. Например, передайте доску в качестве аргумента, а при рекурсивном вызове передайте копию доски.   -  person juanpa.arrivillaga    schedule 08.01.2021
comment
Обратите внимание: ваша функция ничего не возвращает. Он мутирует глобальный объект (плохая практика в целом). (ну, иногда он возвращает False, но это может быть что угодно, поскольку вы никогда не используете возвращаемое значение)   -  person juanpa.arrivillaga    schedule 08.01.2021
comment
Да, предполагается изменить переменную плату, но это не так. Я собираюсь передать board в качестве аргумента вместо использования глобального   -  person CLSigma    schedule 08.01.2021
comment
Хорошо, я не знаю, как сделать это яснее: это меняет доску. Но затем вы измените его обратно. Если у меня есть список, x = [1,2,3]. затем я меняю средний элемент, x[1] = 99, но затем я меняю его обратно x[1] = 2 что еще вы ожидаете?   -  person juanpa.arrivillaga    schedule 08.01.2021


Ответы (2)


Ваше возвращение то, что вы считаете пустой сеткой, где вы помещаете board[row][col] = 0 в def solve_sudoku(): в части

                    if valid(row, col, number):
                        board[row][col] = number
                        solve_sudoku()
                        board[row][col] = 0

поэтому значения снова обнуляются после рекурсивной операции.

Жду вашего следующего испытания.

Удачи.

person Nour-Allah Hussein    schedule 08.01.2021
comment
Спасибо за ваш отзыв. - person CLSigma; 08.01.2021

Если вы не возражаете против обратной связи по соглашению о кодировании:

valid() использует диапазон (0, N), аsolv_sodoku() использует диапазон (N). Они эквивалентны. Лучше быть последовательным. Последний предпочтительнее, потому что он редкий.

Слишком частое использование жестко закодированного числа «9». Вы должны предпочесть лен (доска). Или установите константу вроде: matrix_size = 9 и везде ссылайтесь на matrix_size. Подумайте о создании набора кодов, который будет поддерживать матрицу платы 8x8, изменив только исходную матрицу.

for number in range(1,10) работает, но не пересекается с остальным кодом. Я предлагаю вам попробовать:

for i in range(len(board)):
    number = i + 1
    if valid(col, row, number)
person Joseph Brennan    schedule 08.01.2021
comment
Спасибо за ваш отзыв. - person CLSigma; 08.01.2021