Python -- IndexError: list index out of range (sudoku solver program)

Python -- IndexError: list index out of range (sudoku solver program)

如果这段代码不是最容易理解的,我很抱歉。所以我有一个二维列表 board,尺寸为 9x9(数独板)。在 solve 函数的其中一行中,我检查以查看 if row <= 8 and column <=8:,然后调用 add1 函数。当我使用列出的测试值时,最后一个单元格的永久值为 9,虽然程序仍然解决了电路板,但在调用 add1 时仍然会出现 IndexError: list index out of range。如果我只调用 add1 函数 如果 索引值有效,我不明白这是怎么回事。

class Cell:
    def __init__(self, value, isPermanent):
        self.value = 0
        self.isPermanent = False


def solve(board):  # solves the board
    row = 0  # begin in the first cell in the first row
    column = 0
    while row != 9:  # while there are still empty spaces in the 9 rows,
        if row <= 8 and column <= 8: # HOW DOES A LIST INDEX ERROR COME UP IN
                                     # THE NEXT LINE IF I CHECK THESE VALUES HERE?
            row, column = add1(board, row, column)  # add 1 to the current cell
        printBoard(board)
        print(), print()
        if valid(board) is True:  # if the board is valid,
            if column == 8:  # if in the last cell of a row,
                row += 1  # move up one row, and begin in the first cell
                column = 0
            else:  # otherwise, move on to the next cell
                column += 1
            continue  # restart
        if valid(board) is False:  # if the board is invalid,
            if board[row][column].value == 9:  # if the value of the current cell is equal to 9,
                board[row][column].value = 0  # set it equal to 0
                if column == 0:  # if in the first cell of a row,
                    row -= 1  # go back a row, and into the last cell
                    column = 8
                else:  # otherwise, move back to the previous cell
                    column -= 1
            continue  # restart


def add1(board, row, column):  # increments each cell
    while True:
        if board[row][column].isPermanent:
            if column == 8:
                row += 1
                column = 0
            else:
                column += 1
            continue
        if board[row][column].value == 9:  # if the value of the cell is equal to 9,
            board[row][column].value = 0  # set it equal to 0
            if column == 0:  # if in the first cell of a row,
                row -= 1  # go back a row, to the last cell
                column = 8
            else:  # if not in the first cell,
                column -= 1  # go to the previous cell
        board[row][column].value += 1  # add 1 to the current cell
        return row, column  # return the new coordinate of the current cell


def valid(board):
    for i in range(1, 10):
        if checkRowsForDuplicate(board, i) is False:
            return False
        if checkColumnsForDuplicate(board, i) is False:
            return False
        if checkZonesForDuplicate(board, i) is False:
            return False
    return True


def checkRowsForDuplicate(board, x):
    for row in board:
        line = []
        for cell in row:
            line.append(cell.value)
        if line.count(x) > 1:
            return False


def checkColumnsForDuplicate(board, x):
    for i in range(0, 9):
        column = []
        for row in board:
            column.append(row[i].value)
        if column.count(x) > 1:
            return False


def checkZonesForDuplicate(board, x):
    y = [0, 3, 6]
    z = [3, 6, 9]
    for i in range(3):
        for j in range(3):
            if checkSingleZone(board, x, y[i], z[i], y[j], z[j]) is False:
                return False
    return True


def checkSingleZone(board, x, rowStart, rowEnd, columnStart, columnEnd):
    zoneValues = []
    for row in board[rowStart:rowEnd]:
        for column in row[columnStart:columnEnd]:
            zoneValues.append(column.value)
    if zoneValues.count(x) > 1:
        return False


def printBoard(board):
    for row in board:
        line = []
        for cell in row:
            line.append(cell.value)
        print(line)


def initializeBoard():
    board = [[], [], [], [], [], [], [], [], []]
    for row in board:
        for i in range(0, 9):
            row.append(Cell(0, False))
    return board

board = initializeBoard()

# test values
board[0][0].value = 9
board[0][0].isPermanent = True

board[8][8].value = 9
board[8][8].isPermanent = True

board[2][7].value = 9
board[2][7].isPermanent = True

board[4][1].value = 9
board[4][1].isPermanent = True

solve(board)

我可以很容易地重现你的回溯:

>>> row, column = 8, 8
>>> board[row][column].isPermanent = True
>>> add1(board, row, column)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in add1
IndexError: list index out of range

那是因为你没有检查边界就进入了这个循环:

def add1(board, row, column):  # increments each cell
    while True:
        if board[row][column].isPermanent:
            if column == 8:
                row += 1
                column = 0
            else:
                column += 1
            continue

因此 column == 8 为真,您将 row 增加到 9 并在下一次迭代中命中 board[9]

具有讽刺意味的是,您的 board 包含一个有效的、已解决的数独,但您没有检测到这一点。