数独求解器在python中不打印板

问题描述

我一直在研究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

当我认为应该使用coordXcoordY时,在循环中使用xy的地方:

for x in range(coordX,coordY + 3):
        if x == row and y == col:
            continue
        if self.board[x][y] == val:
            return False

否则,您将一遍又一遍地重复相同的测试。我在印制电路板时遇到的最后一个问题是,电路板中的内容是intstr的混合体-您需要对此有所了解,并且只能使用其中之一。 >

下面是我对您的代码的重做,它解决了我手头的一个数独测试:

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)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...