当前位置: 首页 > 知识库问答 >
问题:

Python中的数独检查器

颛孙子民
2023-03-14

我正在尝试在python中创建一个数独检查器:

ill_formed = [[5,3,4,6,7,8,9,1,2],
              [6,7,2,1,9,5,3,4,8],
              [1,9,8,3,4,2,5,6,7],
              [8,5,9,7,6,1,4,2,3],
              [4,2,6,8,5,3,7,9],  # <---
              [7,1,3,9,2,4,8,5,6],
              [9,6,1,5,3,7,2,8,4],
              [2,8,7,4,1,9,6,3,5],
              [3,4,5,2,8,6,1,7,9]]
easy = [[2,9,0,0,0,0,0,7,0],
       [3,0,6,0,0,8,4,0,0],
       [8,0,0,0,4,0,0,0,2],
       [0,2,0,0,3,1,0,0,7],
       [0,0,0,0,8,0,0,0,0],
       [1,0,0,9,5,0,0,6,0],
       [7,0,0,0,9,0,0,0,1],
       [0,0,1,2,0,0,3,0,6],
       [0,3,0,0,0,0,0,5,9]]

我期待这样的输入——一个9个列表的列表。零表示用户尚未填写的数字。它们可以在一行、一列或3x3中多次出现。

def check_sudoku(grid):
if len(grid) == 9:
    numsinrow = 0
    for i in range(9):
        if len(grid[i]) == 9:
            numsinrow += 1
    if numsinrow == 9:
        for i in range(9):
            rowoccurence = [0,0,0,0,0,0,0,0,0,0]
            for j in range(9):
                rowoccurence[grid[i][j]] += 1
                temprow = rowoccurence[1:10]
                if temprow == [1,1,1,1,1,1,1,1,1]:
                    return True
                else:
                    return False
    else:
        return False
else:
    return False

我显然需要检查是否有一个9x9列表(网格),以及每行、每列和3x3小正方形中是否没有重复项。在代码中,我首先检查行数是否正确(应该有9行)。然后我检查每一行中是否有9个元素(在病态示例中,您可以看到情况并非如此)。然后我尝试检查每一行中的重复项,但我在这样做时遇到了一些问题。我想我可以循环每一行,循环该行中的每一个元素,并在int列表中添加1(rowOccurrence)。例如,如果第一个数字是2,则rowoccurence[2]应等于1。零位于rowoccurence[0]中,未被选中(我有一个临时列表,它应该包含除第一个元素(零)之外的所有元素,因为一行中可能有多个零,并且网格可能仍然是合法的)。我试图对照正确值的参考列表检查临时列表(基本上是RowOccurrence),但它似乎不起作用。你能帮我检查一下这个数独棋盘中的重复行吗?提前非常感谢!

共有3个答案

公冶谦
2023-03-14

我发布这个只是因为大多数其他解决方案几乎不可读,尽管它们可能真的很有效。对于刚开始学习的人来说,我相信下面的代码很有帮助并且非常易读。希望这能帮助任何想要学习如何创建数独检查器的人。

def check_sudoku(grid):
    for row in range(len(grid)):
        for col in range(len(grid)):
            # check value is an int
            if grid[row][col] < 1 or type(grid[row][col]) is not type(1):
                return False
            # check value is within 1 through n.
            # for example a 2x2 grid should not have the value 8 in it
            elif grid[row][col] > len(grid):
                return False
    # check the rows
    for row in grid:
        if sorted(list(set(row))) != sorted(row):
            return False
    # check the cols
    cols = []
    for col in range(len(grid)):
        for row in grid:
            cols += [row[col]]
        # set will get unique values, its converted to list so you can compare
        # it's sorted so the comparison is done correctly.
        if sorted(list(set(cols))) != sorted(cols):
            return False
        cols = []
    # if you get past all the false checks return True
    return True
班承恩
2023-03-14

过早地返回True,因此你永远无法参加你希望失败的测试

            if temprow == [1,1,1,1,1,1,1,1,1]:
                return True  # <-- this is the culprit
            else:
                return False

其他注释:确保某个向量的所有元素都等于某个常数的一个简单方法是:

all(i == const for i in vector)

另一个更简单的方法是:如果 vec[1:10]都是1,那么 sum(vec[1:10])必须是9 (坏主意,见下面的评论。)

游勇军
2023-03-14

请记住,您不是在搜索重复项——只是非零重复项。求和一个集合可以做到这一点。您还可以同时检查行/列的合法性:

def sudoku_ok(line):
    return (len(line) == 9 and sum(line) == sum(set(line)))

def check_sudoku(grid):
    bad_rows = [row for row in grid if not sudoku_ok(row)]
    grid = list(zip(*grid))
    bad_cols = [col for col in grid if not sudoku_ok(col)]
    squares = []
    for i in range(9, step=3):
        for j in range(9, step=3):
          square = list(itertools.chain(row[j:j+3] for row in grid[i:i+3]))
          squares.append(square)
    bad_squares = [square for square in squares if not sudoku_ok(square)]
    return not (bad_rows or bad_cols or bad_squares)
 类似资料:
  • 我正在用python为我的CIS类做作业。我们得给数独棋盘编码。在9x9电路板中,我们显然必须检查每一行、col和3x3正方形是否存在重复项。我对如何用3x3的正方形来检查数字的想法有点固执。下面是我检查每一行和每一列的代码,如果有人能帮我一点轮廓或一种方法,那就是检查每一个3x3的正方形,这将是惊人的!

  • 我已经用Python为非常简单的数独问题编写了一个数独解算器。它的工作原理是检查每个空方块,如果只有一个可能的数字是合法的,则用该数字替换空方块。一旦它完成了整个拼图,如果仍然有1个以上的空方块,它会再次调用新的拼图。我遇到问题的部分是,我希望解算器在每次调用结束时检查谜题是否与调用开始时相同,如果没有更改,这意味着所有剩余的空方块都有超过1个可能值,因此解算器应返回False,以指示解算器无法解

  • 当我试图检查数独的行中是否有重复的元素时,结果什么也没有返回。不知道代码是否正确。如果在一行中找到重复的元素,则需要打印找到的重复项。使用方法帮助我找到解决方案。

  • 我曾经用C语言编写过一个数独谜题,但我陷入了一个问题:检查每个3x3网格是否没有重复的值。这是我的代码: 我知道在function Valid中,我应该有条件检查每个3x3网格,但我没有弄明白:我找到了创建一些变量开始和结束的解决方案,每个变量得到如下结果: 在我的例子中,i和j是ii和jj。 例如,我们发现了这样的东西: 我试过这个密码,但没用。 我不明白这一点:我有下一个数独矩阵: 如果我的代

  • 我已经创建了一个程序,允许用户输入一个数独拼图的所有值,即9x9,将这些值存储在一个数组中,并可以检查所有行和列中的值是否不同,但我很难理解如何实现代码来关注3x3的每个子网格。我想我必须有最后一个嵌套for循环,它可能被3除,但我完全被这部分卡住了。 }

  • 我目前正在创建一个项目,检查给定的9x9数独表是否遵循数独规则。该表存储在一个多维数组中(board[9][9]),我一直在研究如何正确检查每个3x3子网格中是否有重复的数字。我已经建立了0(空白)和9(最大值)之外的数字检查,以及每行和每列中重复的检查。我已经管理了两个create 4 nested for循环,成功地循环了每个3x3框,但我不确定如何检查框中的值是否重复。我对重复的定义是两个包