一旦解决了难题,如何停止产生数独板?

How to stop yielding sudoku boards, once the puzzle is solved?

这是我的递归数独求解器。非常不言自明:

def is_valid(board, num, row, col):
    # check row
    for i in range(9):
        if board[i][col] == num:
            return False

    # check column
    for i in range(9):
        if board[row][i] == num:
            return False

    # check square
    square_w = (row // 3) * 3
    square_h = (col // 3) * 3
    for sRow in range(square_w, square_w + 3):
        for sCol in range(square_h, square_h + 3):
            if board[sRow][sCol] == num:
                return False

    return True

def solve(board):
    for row in range(9):
        for col in range(9):
            if board[row][col] == 0:
                for num in range(1, 10):
                    if is_valid(board, num, row, col):
                        board[row][col] = num
                        yield board
                        yield from solve(board)

                        board[row][col] = 0
                        yield board
                return
    yield board

这是我的板子运行求解器:

bo = [
    [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]
]

问题是,当我调用 solve 并迭代生成的板时,即使在获得结果后板仍继续生成(在 solve 函数的最底部 yield board)。

如何确保生成器中的最后一个值是求解板?

您的代码中存在一些缩进问题。在撰写本文时,returnyield from 语句都应多缩进一层。

要在解决后停止生成更多的板,您应该检查板是否已解决。该代码不会在任何地方执行此操作。

正如您正确指出的那样,当您到达 solve 函数中的最后一个语句并且函数 return 在那里时,棋盘已解决。您可以利用这一刻来标记看板,以便呼叫者更容易知道看板已解决。由于您已经在整个算法中改变了同一个板(而不是产生副本),我想您可以再次改变板以表明它已解决。例如,您可以在左上角存储一个 0。这可以由调用者检查,然后调用者可以立即 return:

def solve(board):
    for row in range(9):
        for col in range(9):
            if board[row][col] == 0:
                for num in range(1, 10):
                    if is_valid(board, num, row, col):
                        board[row][col] = num
                        yield board
                        yield from solve( board)  # corrected wrong indentation
                        if board[0][0] == 0:  # was the board already solved?
                            return  # then get out of here!

                        board[row][col] = 0  # better placed at this indentation
                        yield board  # better placed at this indentation
                return  # corrected wrong indentation
    # the board is the solution: no need to yield it as it was already yielded
    board[0][0] = 0  # mark that no more boards should be yielded