这是一个递归解决数独的代码,不是学校作业。我无法想出如何通过先前的步骤来“回退”。由于第一行没有有效数字,它会在第一行末尾卡住,并继续尝试找到适合那个位置的数字。我遇到问题的函数是“check”。
阅读您的答案后,我更接近了解决方法,但还没有完全解决。它会一直回退并退出递归。
以下是check函数的预期工作方式:
check函数接收棋盘的x和y坐标,并从0,0开始运行一个for循环,从1到9设置第一个在该索引下有效的值,然后移动到下一个索引。当它到达一行的末尾时,它会向下移动一行并回到第一列。如果在索引处没有任何值有效,则将当前索引重置为'.',并将索引向后移动一个并继续计数到9。例如,如果索引0,0处的当前值为2,则继续到3。如果3有效,则向前移动一个索引,以此类推,直到填满棋盘。对于简单的答案,它尝试在每个空索引处使用每个值1-9。
如果不清楚,请告诉我。
此外,这是我使用的棋盘。
阅读您的答案后,我更接近了解决方法,但还没有完全解决。它会一直回退并退出递归。
import sys
class Board:
def __init__(self, grid):
self.grid = grid
self.ogrid = grid
def get_col(self, col):
column = []
for i in self.grid:
column.append(str(i[col]))
return column
def get_row(self, row):
return self.grid[row]
def check_row(self, r, val):
row = self.grid[r]
for i in range(0,9):
if str(val) in row:
return False
return True
def check_col(self, column, val):
col = self.get_col(column)
for i in range(0,9):
if str(val) in col:
return False
return True
def check_square(self, x, y, val):
col = (y//3)*3
row = (x//3)*3
s = ''
for i in range(row, row+3):
for j in range(col, col+3):
s += str(self.grid[i][j])
if str(val) in s:
return False
return True
def check_cell(self, x, y, val):
if self.check_col(y, val) == False:
return False
elif self.check_row(x, val) == False:
return False
elif self.check_square(x, y, val) == False:
return False
return True
def check(self, x, y):
if y == 9:
y = 0
x += 1
if x == 9:
self.print_board()
sys.exit()
if self.ogrid[x][y] == '.':
for val in range(1,10):
if self.check_cell(x, y, val):
self.grid[x][y] = str(val)
self.check(x, y+1)
##I don't think the reset is working and I'm not sure why
if self.ogrid[x][y] == '.': #reset index
self.grid[x][y] = '.'
self.print_board() #Notice it never prints a '.' in spots that have changed
else:
self.check(x,y+1)
return
def print_board(self):
for i in range(0,9):
for j in range(0,9):
sys.stdout.write(self.grid[i][j])
if j == 2 or j == 5:
sys.stdout.write(' ')
if i == 2 or i == 5:
sys.stdout.write('\n')
print('')
def main():
f = open("./easySudoku.txt",'r')
s = ''
grid = []
row = []
for line in f:
s += line
print line
s = s.replace(' ','')
s = s.replace('\n','')
for i in range(0,9):
row = []
for j in range(0,9):
row.append(s[(i*9) + j])
grid.append(row)
sudoku = Board(grid)
sudoku.check(0,0, 1)
if __name__ == "__main__":
main()
以下是check函数的预期工作方式:
check函数接收棋盘的x和y坐标,并从0,0开始运行一个for循环,从1到9设置第一个在该索引下有效的值,然后移动到下一个索引。当它到达一行的末尾时,它会向下移动一行并回到第一列。如果在索引处没有任何值有效,则将当前索引重置为'.',并将索引向后移动一个并继续计数到9。例如,如果索引0,0处的当前值为2,则继续到3。如果3有效,则向前移动一个索引,以此类推,直到填满棋盘。对于简单的答案,它尝试在每个空索引处使用每个值1-9。
如果不清楚,请告诉我。
此外,这是我使用的棋盘。
..6 ..7 3..
.18 ..9 .5.
5.. ... .64
92. .8. ...
... 763 ...
... .9. .75
63. ... ..8
.9. 3.. 52.
..2 4.. 6..
self.grid
和self.ogrid
是同一个对象。如果你改变其中一个,那么另一个也会被改变。你应该使用deepcopy
或以不同的方式存储网格数据。 - James Pringleogrid
时,它正在改变,尽管它不应该这样。 - SirParselot