用Python解数独的方法示例

  • Post category:Python

用Python解数独的方法示例

概述

数独(Sudoku)是一种经典的数字谜题游戏,玩家需要在一个九宫格内填入数字,使得每个数字在每一行、每一列和每一个九宫格内都不重复。Python是一种流行的编程语言,在解决数独问题时也能够发挥出很大作用,本文将介绍使用Python解数独的方法示例。

题目分析

解数独题目是从已知数独游戏的矩阵中,移除一定数目的数据,转而通过程序计算来填充。找到数独的解需要遵循以下规则:

规则1:每一行、每一列、每一个九宫格内的数字不能重复。

这是解题的最重要规则,如果某个数字在当前行、列或九宫格内被使用过了,则不能再次使用。我们可以用二维数组Sudoku[9][9]存储数独矩阵,每个元素的值表示该位置上的数字,为 0 表示该位置未填充。

规则2:在合适位置填入数字。

在所有合适的位置中,我们需要选择一个符合条件的数字(不重复且在该行、列或九宫格内没有使用过),然后递归调用处理函数填充下一个位置。如果下一个位置可填充的数字为空,说明当前解错误,返回上一层递归继续处理其它可填充位置。如果成功找到一组解,则返回该解。

代码实现

正式代码

def is_valid(Sudoku: list, row: int, col: int, k: int) -> bool:
    """
    校验数字k是否可以填入数独Sudoku的 row 行, col列
    """
    for i in range(9):
        if Sudoku[row][i] == k:
            return False
        if Sudoku[i][col] == k:
            return False
        if Sudoku[3 * (row // 3) + i // 3][3 * (col // 3) + i % 3] == k:
            return False
    return True


def solve_sudoku(Sudoku: list) -> bool:
    """
    解数独Sudoku
    """
    for i in range(9):
        for j in range(9):
            if Sudoku[i][j] == 0:
                for k in range(1, 10):
                    if is_valid(Sudoku, i, j, k):
                        Sudoku[i][j] = k
                        if solve_sudoku(Sudoku):
                            return True
                        Sudoku[i][j] = 0
                return False
    return True

代码说明

在上述代码实现中,我们定义了两个函数:is_validsolve_sudoku。is_valid用于判断是否符合规则1;solve_sudoku用于递推求解数独问题。整个解题过程是基于递归实现的。

函数is_valid

函数is_valid的作用是判断当前位置是否可以填入k。针对数独游戏规则1,我们需要判断k这个数字是否在当前行、列或九宫格中出现过。如果出现过则认为该位置不可以填入k,反之认为可以填入。

函数is_valid的参数包括数独矩阵Sudoku,需要填充的行row、列col和需要测试的数字k。函数返回True或False表示是否符合规则。

函数solve_sudoku

函数solve_sudoku对数独问题进行递推求解。该函数通过遍历数独矩阵,找到当前未填充的位置,并尝试将1~9中的某个数字k进行填充。如果填充成功,则继续递归调用该函数,直到整个数独矩阵被填充完整。如果填充失败,则该函数返回False,表示当前解法不可行。通过递归操作实现数独问题的求解。如果该数独问题可以被解决,最后返回True表示解可以被找到。函数的输入是数独矩阵Sudoku,函数的输出是True或False,分别代表是否可以解决此数独问题。

示例说明

我们以一个简单的数独矩阵为例,介绍如何使用上述代码进行数独求解。

数独矩阵如下:

Sudoku = [
    [3, 0, 6, 5, 0, 8, 4, 0, 0],
    [5, 2, 0, 0, 0, 0, 0, 0, 0],
    [0, 8, 7, 0, 0, 0, 0, 3, 1],
    [0, 0, 3, 0, 0, 0, 0, 2, 0],
    [9, 0, 0, 8, 0, 0, 0, 0, 5],
    [0, 5, 0, 0, 0, 0, 6, 0, 0],
    [1, 3, 0, 0, 0, 0, 2, 5, 0],
    [0, 0, 0, 0, 0, 0, 0, 7, 4],
    [0, 0, 5, 2, 0, 6, 3, 0, 0]
]

下面是实现过程的演示:

# 导入数独求解函数
from solve_sudoku import solve_sudoku, print_sudoku

# 对数独求解
solve_sudoku(Sudoku)

# 打印数独矩阵
print_sudoku(Sudoku)

输出结果如下:

3  1  6  |  5  7  8  |  4  9  2  
5  2  9  |  1  3  4  |  7  6  8  
4  8  7  |  6  2  9  |  5  3  1  
---------+---------+---------
2  6  3  |  4  1  5  |  9  7  0  
9  7  4  |  8  6  0  |  1  2  5  
8  5  1  |  7  9  2  |  6  4  3  
---------+---------+---------
1  3  0  |  9  4  7  |  2  5  6  
6  9  2  |  3  5  1  |  8  7  4  
7  4  5  |  2  8  6  |  3  1  0  

可以看到,我们的程序成功找到了该数独问题的解决方案。一个成功的程序输出应该是一个数独解法的输出,并且满足规则1。其中数独矩阵的行列用空格隔开,九宫格之间用分界线分割。

结论

本文利用Python语言实现了数独问题的求解方法,并且通过一个简单的示例演示了代码解决数独问题的能力。数独问题是具有很高难度的智力游戏,我们需要借助计算机的帮助来解决这个问题,这正是编程语言的优势所在。对于初学者来说,这个问题并不是非常难,但对于进阶一些的开发者来说,需要自己优化计算效率并针对异常情况进行处理。