我已经编写了一个Sudoku求解器,用于Python中非常简单的Sudoku问题。工作原理是检查每个空方块,如果只有一个合法的数字,则用该数字替换空方块。一旦它经历了整个拼图,如果仍然有超过1个空方块,它会再次使用新拼图调用自己。我遇到问题的部分是我希望解算器在每个调用结束时检查拼图是否与调用开始时的拼图相同,如果它没有改变则意味着所有剩余的空方块都有超过1个可能的值,因此求解器应返回False以指示求解器不能解决该特定难题。但是,当我尝试实现它时,Solver只会经历一次拼图并返回False。这是我的代码:
def Solver(puzzle):
oldpuzzle = puzzle
count = 0
for row in range(9):
for col in range(9):
if puzzle[row][col] == '0':
possible, numpossible = getPossible(puzzle, row, col)
if numpossible == 1:
puzzle[row][col] = possible[0]
count += puzzle[row].count('0')
if count > 0:
if oldpuzzle == puzzle:
return False
else:
Solver(puzzle)
else:
return True
getPossible()函数返回可能值列表和列表长度。
这是main()函数:
def main():
puzzle = [
['0','2','0','1','7','8','0','3','0'],
['0','4','0','3','0','2','0','9','0'],
['1','0','0','0','0','0','0','0','6'],
['0','0','8','6','0','3','5','0','0'],
['3','0','0','0','0','0','0','0','4'],
['0','0','6','7','0','9','2','0','0'],
['9','0','0','0','0','0','0','0','2'],
['0','8','0','9','0','1','0','6','0'],
['0','1','0','4','3','6','0','5','0']
]
if Solver(puzzle):
print "Solved!"
for row in puzzle:
print ' '.join(row)
else:
print "Failed!"
如何让程序正确比较for循环之前和之后的拼图状态?
答案 0 :(得分:1)
你的问题是这一行:
oldpuzzle = puzzle
将引用设为puzzle
,称为oldpuzzel
而不是副本,因此它们始终相同 - 您需要复制{{ 1}} puzzle
与oldpuzzle
或更多只需设置标记:
copy.copy
并在:
def Solver(puzzle):
Changed = False
然后检查更改是否为False返回。
答案 1 :(得分:1)
您要将puzzle
的引用设置为oldpuzzle
,因此如果对puzzle
进行任何更改,它也会反映在oldpuzzle
中。 puzzle
始终等于oldpuzzle
。
我认为您不需要将拼图设置为旧拼图(或者您需要在开始时保存完整拼图)。
根据逻辑,0
个单元格的数量永远不会增加,之前标记为非零的单元格永远不会被标记为0
。
因此,您可以在开始时存储0
的计数,然后在结束时检查0
的计数是否已更改,如果它已经好了,否则返回假
示例代码 -
def Solver(puzzle):
oldcount = sum(1 for row in puzzle for cell in row if cell == '0')
count = 0
for row in range(9):
for col in range(9):
if puzzle[row][col] == '0':
possible, numpossible = getPossible(puzzle, row, col)
if numpossible == 1:
puzzle[row][col] = possible[0]
count += puzzle[row].count('0')
if count > 0:
if oldcount == count:
return False
else:
Solver(puzzle)
else:
return True
答案 2 :(得分:0)
问题是if oldpuzzle == puzzle
始终是真的,因为创建oldpuzzle
时它不会成为拼图列表的副本,而是重复。这意味着如果您更改puzzle
,则oldpuzzle
也会更改。
list1 = [1, 2, 3]
list2 = list1
list1[0] = 4
print(list2)
# this will print [4, 2, 3]
使oldpuzzle
puzzle
副本的一种方法是使用副本库。在这种情况下,需要制作puzzle
的深层副本,因为它是包含列表的列表。一种方法是使用deep copy function from the copy library。所以函数看起来像这样:
from copy import deepcopy # at the top of the document
def Solver(puzzle):
oldpuzzle = deepcopy(puzzle)
count = 0
# ... and then the rest