问题描述
我一直在研究python程序来解决数独难题,但是我不确定自己做错了什么。我以为我已经修复了它,但是现在我无法得到它来印刷电路板或解决它。我已经写了要解决的算法以及创建电路板的功能。如果有人可以告诉我哪里出错了,请多谢。这是我的代码(抱歉缩进错误-它们是由复制和粘贴引起的):
class Sudoku:
def __init__(self,board,cells):
self.board = board
self.cells = cells
#Creates a board
def newboard(self):
values = self.cells.split(" ")
val_counter = 0
if len(values) != 81:
print("Error: Not enough values.")
exit()
else:
for i in range(9):
for j in range(9):
self.board[i][j] = values[val_counter]
val_counter += 1
# Returns row
def findValidRow(self):
for i in range(9):
for j in range(9):
if int(self.board[i][j]) == 0:
return int(i)
return -1
# Returns col
def findValidCol(self):
for i in range(9):
for j in range(9):
if int(self.board[i][j]) == 0:
return int(j)
return -1
def possible(self,row,col,val):
# Check row for value
for i in range(9):
if self.board[row][i] == val:
return False
# Checks col for value
for j in range(9):
if self.board[j][col]:
return False
# Checks square for value
coordX,coordY = 3 * (row // 3),3 * (col // 3)
for x in range(coordX,coordX + 3):
for y in range(coordY,coordY + 3):
if coordX == row and coordY == col:
continue
if self.board[coordX][coordY] == val:
return False
return True
# Solves the board
def solve(self):
# Checks if cells are all solved
if self.findValidCol() == -1:
print(self.board)
return True
# Finds first cell to fill
row = self.findValidRow()
col = self.findValidCol()
for i in range(1,10):
if self.possible(row,i):
self.board[row][col] = i
# Updates values to find new cell to fill
if self.solve():
return True
# Backtracks
self.board[row][col] = 0
return False
# Get cell values and calls solve function
get_cells = input("Enter cell values seperated by 1 space. Enter 0 for empty cells: ")
b = Sudoku([[0,0],[0,0]],get_cells)
b.newboard()
b.solve()
解决方法
您的第一个问题在这里:
# Check row for value
for i in range(9):
if self.board[row][i] == val:
return False
# Checks col for value
for j in range(9):
if self.board[j][col]:
return False
具体来说,该行:
if self.board[j][col]:
应为:
if self.board[j][col] == val:
下一个问题在这里:
coordX,coordY = 3 * (row // 3),3 * (col // 3)
for x in range(coordX,coordX + 3):
for y in range(coordY,coordY + 3):
if coordX == row and coordY == col:
continue
if self.board[coordX][coordY] == val:
return False
当我认为应该使用coordX
和coordY
时,在循环中使用x
和y
的地方:
for x in range(coordX,coordY + 3):
if x == row and y == col:
continue
if self.board[x][y] == val:
return False
否则,您将一遍又一遍地重复相同的测试。我在印制电路板时遇到的最后一个问题是,电路板中的内容是int
和str
的混合体-您需要对此有所了解,并且只能使用其中之一。 >
下面是我对您的代码的重做,它解决了我手头的一个数独测试:
class Sudoku:
def __init__(self,board,cells):
self.board = board
self.cells = cells
def newBoard(self):
''' Creates a board '''
values = self.cells.split(" ")
assert len(values) == 81,"Error: Not enough values."
for i in range(9):
for j in range(9):
self.board[i][j] = int(values.pop(0))
def findValidCell(self):
''' Returns empty cell indicies or None '''
for row in range(9):
for col in range(9):
if self.board[row][col] == 0:
return (row,col)
return None
def possible(self,row,col,val):
# Check row for value
for i in range(9):
if self.board[row][i] == val:
return False
# Checks col for value
for j in range(9):
if self.board[j][col] == val:
return False
# Checks square for value
coordX,3 * (col // 3)
for x in range(coordX,coordX + 3):
for y in range(coordY,coordY + 3):
if x == row and y == col:
continue
if self.board[x][y] == val:
return False
return True
def printBoard(self):
print(*self.board,sep='\n')
def solve(self):
''' Solves the board '''
# Checks if cells are all solved
cell = self.findValidCell()
if cell is None:
return True
# Finds first cell to fill
row,col = cell
for i in range(1,10):
if self.possible(row,i):
self.board[row][col] = i
# Updates values to find new cell to fill
if self.solve():
return True
# Backtracks
self.board[row][col] = 0
return False
# Get cell values and calls solve function
get_cells = input("Enter cell values separated by 1 space. Enter 0 for empty cells: ")
b = Sudoku([
[0,0],[0,],get_cells)
b.newBoard()
if b.solve():
b.printBoard()
,
@cdlane给出的答案非常有效。我刚刚注意到我可以使用一些优化来提高possible
函数的性能,结果是:
def possible(self,val):
# Check row or column for value
for i in range(9):
if (self.board[row][i] == val) or (self.board[i][col] == val):
return False
# Checks 3x3 containing square for value
coordX,3 * (col // 3)
for x in range(coordX,coordX + 3):
for y in range(coordY,coordY + 3):
if self.board[x][y] == val:
return False
return True
您可以看到我在同一for
循环中检查行和列,并且消除了
不必要的单元格位置检查,因为候选单元格在该点包含零。
并且因为我喜欢错误消息中的更多信息,所以将断言修改为:
assert len(values) == 81,"Error: {} values {} != {}".format(("Not enough"if len(values)<81 else "Too many"),len(values),81)