断言错误失败 - 找不到原因 - Norvig 数独

0 投票
2 回答
680 浏览
提问于 2025-04-18 05:27

我正在研究彼得·诺维格的数独解题程序,但在以下这一行遇到了问题:

assert peers['C2'] == (['A2', 'B2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2',
                        'C1', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9',
                        'A1', 'A3', 'B1', 'B3'])

我收到了以下错误信息:

Traceback (most recent call last):
  File "Sudoku.py", line 56, in <module>
    test()
  File "Sudoku.py", line 33, in test
    'A1', 'A3', 'B1', 'B3'])
AssertionError

我尝试用以下代码进行调试,但没有发现任何不同的地方……

pprint(peers['C2'])
peersc2 = ['A2', 'B2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2', 'C1', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'A1', 'A3', 'B1', 'B3']
print(list(set(peersc2) - set(peers['C2'])))

这是代码:

# http://norvig.com/sudoku.html

# from pprint import pprint

# concatenates letter and number to create cell
def cross(A, B):
    return [a + b for a in A for b in B]


def test():
    # 9 rows and 9 cols
    assert len(squares) == 81
    # row, col, and 9x9 square
    assert len(unitlist) == 27
    # each square 3 x 3
    assert all(len(units[s]) == 3 for s in squares)
    # row + col + square - repeats
    assert all(len(peers[s]) == 20 for s in squares)
    # should be row, column, and square for cell
    assert units['C2'] == [['A2', 'B2', 'C2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2'],
                           ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9'],
                           ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']]

    # Next assertion fails
    # pprint(peers['C2'])
    # peersc2 = ['A2', 'B2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2', 'C1', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'A1',
    #            'A3', 'B1', 'B3']
    # print(list(set(peersc2) - set(peers['C2'])))

    # should be row, column, and square without repeats
    assert peers['C2'] == (['A2', 'B2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2',
                            'C1', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9',
                            'A1', 'A3', 'B1', 'B3'])


digits = '123456789'
rows = 'ABCDEFGHI'
cols = digits
# makes each square
squares = cross(rows, cols)

# Creates arrays with each row 'A1', 'B1', 'C1', etc.
unitlist = ([cross(rows, c) for c in cols] +
            [cross(r, cols) for r in rows] +
            [cross(rs, cs) for rs in ('ABC', 'DEF', 'GHI') for cs in
             ('123', '456', '789')])
# assigns cell to all associated rows, columns, and squares
# ex) I5 > A5-I5 + I1-I9 + G4-G6, H4-H6, I4-I6
units = dict((s, [u for u in unitlist if s in u])
             for s in squares)
# creates the row and col pairs for each cell
# A1 = A1-I1 + A1-A9 + A1-A3, B1-B3, C1-C3
peers = dict((s, set(sum(units[s], [])) - set([s]))
             for s in squares)

test()

提前感谢大家的帮助!

2 个回答

1

peers 是一个字典,它把字符串映射到集合,而不是列表。

集合和列表即使内容相同,它们也永远不相等。请确认你有一个集合:

assert peers['C2'] == set(['A2', 'B2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2',
                           'C1', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9',
                           'A1', 'A3', 'B1', 'B3'])

这样检查就能通过了。

如果你查看原始代码,你会发现原始代码正是这样做的。

1

因为 peers 是把字符串映射到 集合,而不是列表,所以你可以把 set() 转换成列表:

如你所见,如果我们在 Python 的命令行中运行你的代码:

>>> peers['C2']
set(['F2', 'G2', 'H2', 'D2', 'I2', 'C9', 'C6', 'A1', 'A3', 'C8', 'B1', 'B2', 'B3', 'C3', 'C1', 'E2', 'C7', 'A2', 'C5', 'C4'])
>>> 

因此,你需要把它转换成一个 集合

# http://norvig.com/sudoku.html

# from pprint import pprint

# concatenates letter and number to create cell
def cross(A, B):
    return [a + b for a in A for b in B]


def test():
    # 9 rows and 9 cols
    assert len(squares) == 81
    # row, col, and 9x9 square
    assert len(unitlist) == 27
    # each square 3 x 3
    assert all(len(units[s]) == 3 for s in squares)
    # row + col + square - repeats
    assert all(len(peers[s]) == 20 for s in squares)
    # should be row, column, and square for cell
    assert units['C2'] == [['A2', 'B2', 'C2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2'],
                           ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9'],
                           ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']]

    # Next assertion fails
    # pprint(peers['C2'])
    # peersc2 = ['A2', 'B2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2', 'C1', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'A1',
    #            'A3', 'B1', 'B3']
    # print(list(set(peersc2) - set(peers['C2'])))

    # should be row, column, and square without repeats
    assert peers['C2'] == set(['A2', 'B2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2',
                            'C1', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9',
                            'A1', 'A3', 'B1', 'B3'])


digits = '123456789'
rows = 'ABCDEFGHI'
cols = digits
# makes each square
squares = cross(rows, cols)

# Creates arrays with each row 'A1', 'B1', 'C1', etc.
unitlist = ([cross(rows, c) for c in cols] +
            [cross(r, cols) for r in rows] +
            [cross(rs, cs) for rs in ('ABC', 'DEF', 'GHI') for cs in
             ('123', '456', '789')])
# assigns cell to all associated rows, columns, and squares
# ex) I5 > A5-I5 + I1-I9 + G4-G6, H4-H6, I4-I6
units = dict((s, [u for u in unitlist if s in u])
             for s in squares)
# creates the row and col pairs for each cell
# A1 = A1-I1 + A1-A9 + A1-A3, B1-B3, C1-C3
peers = dict((s, set(sum(units[s], [])) - set([s]))
             for s in squares)

test()

然后如果我们运行你的程序:

bash-3.2$ python sudokusolver.py
bash-3.2$ 

就不会出现错误了!

希望这对你有帮助!

撰写回答