【发布时间】:2014-07-04 10:19:11
【问题描述】:
我对 Python 比较陌生,我一直在解决 checkio.com 上的问题,其中一些我觉得很有趣。
我目前正在解决的问题是数独求解器(如果有人需要我写出数独规则,我很乐意帮忙)。
我决定尝试使用回溯和递归函数来解决问题。该函数采用二维数组形式的初始数独网格输入,零表示空单元格。
这里是我的代码的核心部分:
def checkio(grid,depth=0):
# Return the solution of the sudoku
# or False if the current grid has no solution
# uses backtracking
# depth is for debugging
for p in range(9):
for q in range(9):
if grid[p][q]==0:
candidates=cand(p,q,grid)
for x in candidates:
#try each candidate in turn
grid[p][q]=x
#print out information for debugging
print("working on cell (%s,%s) --> depth %s, candidate is %s" % (p,q,depth,x))
print_sudoku(grid)
h=checkio(grid,depth+1)
#h is False unless we have found a full grid
if h:
return h
#return false if no candidate works
return False
#if the grid is already full, just return it
#if the initial input was valid, this algorithm shouldn't produce an invalid grid
return grid
这是我正在使用的子程序,它们似乎工作正常:
def print_sudoku(grid):
# prints out the grid in a way that's easier to parse visually
for x in grid:
print(x)
def cand(i,j,grid):
# returns a list of candidate numbers for the square (i,j)
rowdata=[]
for n in range(9):
if grid[i][n]!=0:
rowdata.append(grid[i][n])
coldata=[]
for n in range(9):
if grid[n][j]!=0:
coldata.append(grid[n][j])
boxdata=[]
for p in range(9):
for q in range(9):
if samebox(p,q,i,j) and grid[p][q]!=0:
boxdata.append(grid[p][q])
fulllist=range(1,10)
cand=list(set(fulllist) - set(rowdata + coldata + boxdata))
return cand
def samebox(ax,ay,bx,by):
#returns true if (ax,ay) and (bx,by) are in the same box
return ax // 3 == bx // 3 and ay // 3 == by // 3
这是一个示例函数调用,其中输入网格已知(唯一)可解:
checkio([[0,7,1,6,8,4,0,0,0],[0,4,9,7,0,0,0,0,0],[5,0,0,0,0,0,0,0,0],[0,8,0,0,0,0,5,0,4],[0,0,0,3,0,7,0,0,0],[2,0,3,0,0,0,0,9,0],[0,0,0,0,0,0,0,0,9],[0,0,0,0,0,3,7,2,0],[0,0,0,4,9,8,6,1,0]])
现在,我希望这段代码可以工作。但是,如果您运行测试示例,它会失败。通过查看中间网格,我们可以看到一个问题:一旦算法尝试了给定的轨道并卡住(即到达没有候选者的空方格),该函数的后续实例的网格(在较低深度下运行) ) 正在使用的函数填充了之前的函数实例留下的(可能不正确的)值(在更高的深度运行)。
我不明白为什么会这样。我认为在每次函数调用时,都会创建一个新的本地范围,以便函数的每个实例都使用自己的网格,而不会影响其他实例的网格。
我是否误解了关于变量范围的某些内容,还是我犯了其他错误?感谢您的宝贵时间。
【问题讨论】:
标签: python