简体   繁体   English

Python中的数独难题

[英]Sudoku puzzle in Python

I'm new to python and StackOverflow and trying to write a small program that checks if a sudoku puzzle (ie a series of lists) is correct (True) or incorrect (False). 我是python和StackOverflow的新手,并尝试编写一个小程序来检查数独难题(即一系列列表)是正确的(True)还是不正确的(False)。

So I broke it down by writing 2 functions, one that checks ROWS (ie checks that there is one of EACH number from 1-n - where n is the length of the list - in each list) and one function that checks COLUMNS (to make sure there is no crossover of elements down the lists, and that there is only one of each number from 1-n in position 0, 1, and so forth). 因此,我通过编写2个函数将其分解,其中一个函数检查ROWS(即,检查每个列表中是否存在1-n的每个EACH编号- 其中n是列表的长度 ),而另一个功能则检查COLUMNS(到确保列表中没有元素交叉,并且在位置0、1等的从1-n的每个数字中只有一个)。

The first function is working fine, but the second one (checking columns) seems to constantly output 'True' even when the puzzle is incorrect. 第一个功能运行良好,但是第二个功能(检查列)似乎始终输出“ True”,即使拼图不正确也是如此。 For example, for the list 例如,对于列表
myList = myList =
[[1,2,3], [[1,2,3],
[3,1,2], [3,1,2],
[3,2,3]], [3,2,3],
the output is True, when the puzzle is wrong. 拼图错误时,输出为True。 I have tried to spot the problem lots of times by going through with egs line by line, but to no avail! 我试图通过逐行进行例如egs来多次发现问题,但无济于事! Can anyone spot what it is I've done wrong, or share any better ways of coding a sudoku-checker? 谁能发现我做错了什么,或者分享编码数独检查程序的更好方法? :) :)
Thank you!! 谢谢!! Here is my code for checking columns: 这是我检查列的代码:

def check_down(list_of_lists):
a = []   #checking list
i = -1   #list
j = 0    #position
n = len(list_of_lists)
while True:
    i = i + 1
    if [list_of_lists[i][j]] in a: #if list element already in a, it is a copy so False
        return False
        break
    elif [list_of_lists[i][j]] not in a:
        a = a + [list_of_lists[i][j]] #if list element not in a then add it
        if i == n-1 and j == n-1: #if loop reaches end of lists, True
                return True
                break
        elif i == n-1 and j!= n-1: #if last list but not last position, move on
                j = j +1           #next position to check
                i = -1             #reset i to -1
                del a[:]           #empty the checking list
    else:
        return False

First off, your flow is really wrong. 首先,您的流程确实是错误的。

You really should not write things like 你真的不应该写像

while True :
    i = i + 1

even if the inside of the while is supposed to break somewhere. 即使那while的内部应该在某个地方破裂。 Instead, since you are iterating over the rows, just do: 相反,由于您要遍历行,因此请执行以下操作:

while i < rowsNumber :
    i = i + 1

Then, you write: 然后,您编写:

if A :
    #stuff
elif not A :
    #other stuff
else :
    #guess what, stuff

But that last else cannot logically be reached. 但是,从逻辑上讲,这最后else是无法实现的。 The right way is: 正确的方法是:

if A :
    #stuff
else :
    #other stuff

Besides, you write a = a + [list_of_lists[i][j]] , which does work, but I would largely prefer a.append(list_of_list[i][j] , which is way more pythonic. 此外,您编写a = a + [list_of_lists[i][j]]确实有效,但是我更喜欢a.append(list_of_list[i][j] ,这更像Python。

Also, you don't need to use break after a return statement, because return stops the execution of the function. 同样,您不需要在return语句后使用break ,因为return停止函数的执行。

Now for your problem: you wrote [list_of_lists[i][j]] in a , which is False , because [list_of_lists[i][j]] is a list. 现在解决您的问题:您将[list_of_lists[i][j]] in a False ,因为[list_of_lists[i][j]]是一个列表。 What you want is [list_of_lists[i][j]] in a , without the brackets. 您想要的是a中的[list_of_lists[i][j]] in a ,没有括号。

I corrected this and tried it on your example, and it did return False . 我已对此进行更正,并在您的示例中进行了尝试,但确实返回False

The problem in your code is that you are checking the existence of a list in list a instead of checking the existence of the number: 代码中的问题是,您正在检查列表a列表的存在,而不是检查数字的存在:

if [list_of_lists[i][j]] in a:

So the brackets around list_of_lists[i][j] are making it a list which contains single element. 因此, list_of_lists [i] [j]周围的括号使它成为包含单个元素的列表。 So you need to remover those brackets and the code will work as expected. 因此,您需要删除这些括号,并且代码将按预期工作。

There are several other improvents as mentioned by @Right Leg . @Right Leg还提到了其他一些改进。

However your logic for Sudoku checker is still wrong as you are missing the grid check. 但是,由于缺少网格检查,因此Sudoku检查器的逻辑仍然错误。 Checking the uniqueness at row level as well as at column level is a necessary condition but it is not sufficient. 在行级别和列级别检查唯一性是必要条件,但还不够。 Consider the following example: 考虑以下示例:

在此处输入图片说明 在此处输入图片说明

在此处输入图片说明 在此处输入图片说明

As you can see in the images above, each row has unique elements, each column has unique elements, but there is duplicacy of elements in each 3x3 grid. 如上图所示,每一行都有唯一的元素,每一列都有唯一的元素,但是每个3x3网格中都有重复的元素。 So even if the answer is False , your solution will return True beacuse you do not have any grid check. 因此,即使答案为False ,您的解决方案也将返回True,因为您没有进行任何网格检查。 So you need to write logic to check uniqueness at grid level as well. 因此,您还需要编写逻辑以在网格级别检查唯一性。

You may use the following code. 您可以使用以下代码。 Note that the following code can be improved by using extra space: 请注意,可以通过使用额外的空间来改进以下代码:

import math

def checkSudoku(sudoku):
    # Check uniqueness in each row.
    for i in range(len(sudoku)):
        lst = []
        for j in range(len(sudoku)):
            if sudoku[i][j] in lst:
                return False
            else:
                lst.append(sudoku[i][j])

    # Check uniqueness in each column.
    for j in range(len(sudoku)):
        lst =[]
        for i in range(len(sudoku)):
            if sudoku[i][j] in lst:
                return False
            else:
                lst.append(sudoku[i][j])

    # Check uniqueness in each grid.
    offset = int(math.sqrt(len(sudoku)))
    for rowStart in range(0,len(sudoku),offset):
        rowEnd = rowStart + offset
        for columnStart in range(0,len(sudoku),offset):
            columnEnd = columnStart + offset

            lst = []
            for i in range(rowStart,rowEnd):
                for j in range(columnStart,columnEnd):
                    if sudoku[i][j] in lst:
                        return False
                    else:
                        lst.append(sudoku[i][j])

    # No test was failed, So return True.     
    return True

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM