代码之家  ›  专栏  ›  技术社区  ›  Ficu

Computerphile的Python解算器-不返回任何值

  •  0
  • Ficu  · 技术社区  · 3 年前

    我刚刚从中复制了代码 this YT video .

    def possible(y, x, n):
        for i in range(9):
            if grid[y, i] == n:
                return False
        for i in range(9):
            if grid[i, x] == n:
                return False
        y0 = (y//3)*3
        x0 = (x//3)*3
        for i in range(3):
            for j in range(3):
                if grid[y0+i, x0+j] == n:
                    return False
        return True
    
    def solve_grid():
        for i in range(9):
            for j in range(9): 
                if grid[i, j] == 0:
                    for n in range(1, 10):
                        if possible(i, j, n):
                            grid[i, j] = n
                            solve_grid() 
                            grid[i, j] = 0
                    return       
        print(grid)
    
    grid = np.array([[0, 6, 0, 0, 4, 0, 0, 8, 5],
                     [0, 8, 9, 0, 0, 5, 0, 1, 7],
                     [0, 3, 0, 0, 0, 1, 0, 0, 0],
                     [0, 5, 3, 0, 6, 0, 7, 0, 0],
                     [0, 0, 2, 0, 1, 7, 0, 9, 0],
                     [1, 0, 0, 9, 2, 0, 0, 4, 0],
                     [0, 0, 0, 8, 0, 0, 0, 0, 9],
                     [4, 0, 7, 0, 0, 0, 6, 0, 0],
                     [8, 0, 5, 3, 9, 0, 2, 0, 0]])
    
    solve_grid()
    

    我想给一个变量赋值,而不是打印它,但是简单地将打印转换成返回结果,结果是没有值。

    有什么想法吗?提前谢谢。

    1 回复  |  直到 3 年前
        1
  •  1
  •   JadeSpy    3 年前

    这其实很有趣。问题不在于返回值,而在于找到解决方案后停止函数。 这个项目似乎找到了所有可能的解决方案,而不仅仅是它遇到的第一个。对于您给出的Sodoku板示例,只有一种解决方案,因此此功能并不明显。 为了让sodoku board退出函数,我们有一些选择:过早地停止函数,只获得第一个结果有点棘手,但只获取所有结果很容易,我甚至不必完全理解函数的流程。我会有一个列表,每次找到一个解决方案时,我都会将当前网格数组的一个副本添加到解决方案集中(从技术上讲,它是一个列表,因为np.array显然是不可散列的)。找出代码中的列表的附加位置很容易,这就是print语句的位置。我只是让列表在旧的返回点返回,而隐式返回在函数的末尾。 唯一值得注意的变化是solve_网格函数。好的,下面是代码:

    import numpy as np
    from pprint import pprint
    def possible(y, x, n):
        for i in range(9):
            if grid[y, i] == n:
                return False
        for i in range(9):
            if grid[i, x] == n:
                return False
        y0 = (y//3)*3
        x0 = (x//3)*3
        for i in range(3):
            for j in range(3):
                if grid[y0+i, x0+j] == n:
                    return False
        return True
    
    def solve_grid(solutions = None):
        if(solutions==None):
            solutions = []
        for i in range(9):
            for j in range(9): 
                if grid[i, j] == 0:
                    for n in range(1, 10):
                        if possible(i, j, n):
                            grid[i, j] = n
                            solve_grid(solutions) 
                            grid[i, j] = 0
                    return solutions     
        #print(grid)
        solutions.append(grid.copy())
        return solutions
    grid = np.array([[0, 0, 0, 0, 0, 0, 0, 8, 5],
                     [0, 8, 9, 0, 0, 5, 0, 1, 7],
                     [0, 3, 0, 0, 0, 1, 0, 0, 0],
                     [0, 5, 3, 0, 6, 0, 7, 0, 0],
                     [0, 0, 0, 0, 1, 7, 0, 9, 0],
                     [1, 0, 0, 9, 0, 0, 0, 4, 0],
                     [0, 0, 0, 8, 0, 0, 0, 0, 9],
                     [4, 0, 7, 0, 0, 0, 6, 0, 0],
                     [8, 0, 5, 3, 9, 0, 2, 0, 0]])
    
    #print(solve_grid())
    pprint(solve_grid())
    

    你也可以做一些事情,让它只找到第一个x的解决方案,这可能会很有趣。最好不要使用全局数组,而是将电路板传递给函数。

        2
  •  0
  •   Dmytro Kolupaiev    3 年前

    我认为这段代码背后的想法是对网格进行一些操作,但使全局网格不可更改。通过使用copy()方法,您仍然可以获得非None值:

    import numpy as np
    
    
    def possible(grid, y, x, n):
        for i in range(9):
            if grid[y, i] == n:
                return False
        for i in range(9):
            if grid[i, x] == n:
                return False
        y0 = (y//3)*3
        x0 = (x//3)*3
        for i in range(3):
            for j in range(3):
                if grid[y0+i, x0+j] == n:
                    return False
        return True
    
    
    def solve_grid(grid):
        g = grid.copy()
        for i in range(9):
            for j in range(9):
                if g[i, j] == 0:
                    for n in range(1, 10):
                        if possible(g, i, j, n):
                            g[i, j] = n
        return g
    
    
    grid = np.array([[0, 6, 0, 0, 4, 0, 0, 8, 5],
                     [0, 8, 9, 0, 0, 5, 0, 1, 7],
                     [0, 3, 0, 0, 0, 1, 0, 0, 0],
                     [0, 5, 3, 0, 6, 0, 7, 0, 0],
                     [0, 0, 2, 0, 1, 7, 0, 9, 0],
                     [1, 0, 0, 9, 2, 0, 0, 4, 0],
                     [0, 0, 0, 8, 0, 0, 0, 0, 9],
                     [4, 0, 7, 0, 0, 0, 6, 0, 0],
                     [8, 0, 5, 3, 9, 0, 2, 0, 0]])
    
    
    grid1 = solve_grid(grid)
    
    print(grid)
    print(grid1)