简体   繁体   English

python数独难题? 前后检查难题

[英]python sudoku puzzle? checking puzzle before and after

I have written a Sudoku solver for very easy Sudoku problems in Python. 我已经为Python中非常简单的Sudoku问题编写了Sudoku求解器。 How it works is by checking each empty square, and if there is only one possible number that is legal, then replace the empty square with that number. 它的工作方式是检查每个空方格,如果只有一个合法的可能数字,则用该数字替换空方格。 Once it has gone through the whole puzzle, if there are still more than 1 empty squares, it calls itself again with the new puzzle. 一旦遍历整个拼图,如果仍然有超过1个空方块,它将使用新拼图再次调用自身。 The part where I am having problems is I want the solver to check at the end of each call if the puzzle is the same as it was at the beginning of the call, and if it has not changed that means that all remaining empty squares have more than 1 possible value, and therefore the solver should return False to indicate that the solver isn't capable of solving that particular puzzle. 我遇到问题的部分是我希望求解器在每次调用结束时检查谜题是否与调用开始时相同,并且如果它没有更改,则意味着所有剩余的空白方块都有大于1的可能值,因此求解器应返回False,以指示求解器无法解决该特定难题。 However, when I tried to implement this, the Solver only goes through the puzzle once and returns False. 但是,当我尝试实现此功能时,求解器只经历了一次难题,然后返回False。 Here is my code: 这是我的代码:

def Solver(puzzle):

    oldpuzzle = puzzle
    count = 0

    for row in range(9):

        for col in range(9):
            if puzzle[row][col] == '0':
                possible, numpossible = getPossible(puzzle, row, col)

                if numpossible == 1:
                    puzzle[row][col] = possible[0]
        count += puzzle[row].count('0')

    if count > 0:
        if oldpuzzle == puzzle:
            return False
        else:
            Solver(puzzle)
    else:
        return True

The getPossible() function returns a list of possible values and the length of the list. getPossible()函数返回可能值的列表以及列表的长度。

Here is the main() function: 这是main()函数:

def main():

puzzle = [ ['0','2','0','1','7','8','0','3','0'], ['0','4','0','3','0','2','0','9','0'], ['1','0','0','0','0','0','0','0','6'], ['0','0','8','6','0','3','5','0','0'], ['3','0','0','0','0','0','0','0','4'], ['0','0','6','7','0','9','2','0','0'], ['9','0','0','0','0','0','0','0','2'], ['0','8','0','9','0','1','0','6','0'], ['0','1','0','4','3','6','0','5','0'] ] if Solver(puzzle): print "Solved!" for row in puzzle: print ' '.join(row) else: print "Failed!"

How can I get the program to properly compare the state of the puzzle before and after the for loop? 我如何获得该程序以正确比较for循环之前和之后的拼图状态?

Your problem is that the line: 您的问题是该行:

oldpuzzle = puzzle

Makes a reference to puzzle called oldpuzzel not a copy so they are always the same - you need to either copy the puzzle to oldpuzzle with copy.copy or more simply set a flag: 引用名为oldpuzzel puzzle oldpuzzel 不是副本,因此它们始终相同-您需要使用copy.copypuzzle复制到oldpuzzle ,或者更简单地设置一个标志:

def Solver(puzzle):
   Changed = False

and in the: 并在:

          if numpossible == 1:
               Changed = True

Then check changed if it is False return it. 然后检查更改是否为False返回它。

You are setting the reference of puzzle to oldpuzzle , hence if you do any changes to puzzle , it will reflect in oldpuzzle as well. 您将puzzle的参考设置为oldpuzzle ,因此,如果您对puzzle进行任何更改,它也会在oldpuzzle反映oldpuzzle and puzzle would always be equal to oldpuzzle . puzzle永远等于oldpuzzle

I do not think you need to set the puzzle to old puzzle (or you need to save the complete puzzle at the start). 我认为您无需将拼图设置为旧拼图(或一开始就需要保存完整的拼图)。

According to the logic, the number of 0 cells would never increase and a cell that is marked non-zero previously would never become marked 0 . 根据逻辑, 0单元的数量将永远不会增加,并且以前标记为非零的单元将永远不会变为0

Hence you can just store the count of 0 s at the start, and then at the end check if the count of 0 s has changed or not, if it has then good, otherwise return False. 因此,您可以只在开始时存储0 s的计数,然后在结束时检查0 s的计数是否已更改,如果它已经变好,则返回False。

Example code - 示例代码-

def Solver(puzzle):

    oldcount = sum(1 for row in puzzle for cell in row if cell == '0')
    count = 0

    for row in range(9):

        for col in range(9):
            if puzzle[row][col] == '0':
                possible, numpossible = getPossible(puzzle, row, col)

                if numpossible == 1:
                    puzzle[row][col] = possible[0]
        count += puzzle[row].count('0')

    if count > 0:
        if oldcount == count:
            return False
        else:
            Solver(puzzle)
    else:
        return True

The problem is that if oldpuzzle == puzzle will always be true because when oldpuzzle is created it doesn't become a copy of the puzzle list but rather a duplicate. 问题在于, if oldpuzzle == puzzle将始终为真,因为在创建oldpuzzle时,它不会成为拼图列表的副本,而是一个副本。 This means that if you change puzzle then oldpuzzle will also change. 这意味着,如果您更改puzzle那么oldpuzzle puzzle也会更改。

list1 = [1, 2, 3]
list2 = list1
list1[0] = 4
print(list2)
# this will print [4, 2, 3]

One way to make oldpuzzle a copy of puzzle is to use the copy library. 使oldpuzzle成为puzzle副本的一种方法是使用副本库。 In this case it is required to make a deep copy of puzzle because it is a list with list in it. 在这种情况下,需要制作puzzle的深层副本,因为它是其中包含列表的列表。 One way to do this is to use the deep copy function from the copy library . 一种方法是使用复制库中深度复制功能 So the function would look something like this: 因此该函数将如下所示:

from copy import deepcopy # at the top of the document

def Solver(puzzle):

    oldpuzzle = deepcopy(puzzle)
    count = 0

    # ... and then the rest

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

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