📜  生成有效的数独板python(1)

📅  最后修改于: 2023-12-03 14:56:16.775000             🧑  作者: Mango

生成有效的数独板 Python

数独,也称作九宫格,是一类源自18世纪瑞士的数学难题。数独棋盘为9×9的格子,每行、每列、每个3×3的九宫格内都分别填了1-9的数字。本文将介绍如何使用 Python 生成一个有效的数独板。

数独生成算法

数独生成算法的核心思想是“填数”和“尝试”。先随机把1-9填进数独的第一行,然后根据数独的要求继续填后面的格子。假设现在想要填第(i, j)个格子,那么需要先判断这个格子前面的已经填好的数是否符合数独规则。

如果符合规则,那么我们就填这个格子,然后递归下去填下一个格子。如果递归到第81个格子,说明已经生成了一个数独棋盘,那么就返回它。如果填不了这个格子,说明之前填的数字有问题,那就返回上一层递归重新尝试填前面的格子。

具体实现时需要注意以下几点:

  • 使用洗牌算法随机生成每一行的数字,保证每一行都是随机的;
  • 在尝试填当前格子时,使用1-9的数去填。随机填数可以将1-9看作一个列表,随机打乱列表,每次取第一个数填入格子中;
  • 在尝试填下一个格子时,需要先获取它可能的填数,从小到大排列并依次尝试,这样可以减少尝试的次数,提高算法效率。可能的填数是所有不能填的数的补集。
生成数独板实现

下面是使用 Python 实现的数独生成算法示例代码:

import random


def generate_sudoku():
    # 初始化空棋盘
    grid = [[0 for _ in range(9)] for _ in range(9)]

    # 递归生成数独棋盘
    generate_sudoku_helper(grid, 0, 0)

    return grid


def generate_sudoku_helper(grid, i, j):
    if i == 9:
        # 棋盘填完,返回 True
        return True
    
    if j == 9:
        # 当前行填完,递归到下一行的第一个格子
        return generate_sudoku_helper(grid, i + 1, 0)

    values = list(range(1, 10))
    random.shuffle(values)

    for value in values:
        # 判断当前值是否可以填入当前格子
        if is_valid_value(grid, i, j, value):
            grid[i][j] = value
            # 递归填下一个格子,如果返回 True,说明棋盘填完,直接返回
            if generate_sudoku_helper(grid, i, j + 1):
                return True
            # 否则回溯,清空当前格子,重新尝试下一个值
            grid[i][j] = 0

    # 如果前面的值都尝试过了都填不进去,那就返回 False,表示回溯
    return False


def is_valid_value(grid, i, j, value):
    # 判断当前值是否在行、列、3x3宫内已经出现过
    row_check = all(value != grid[i][k] for k in range(9))
    if row_check:
        column_check = all(value != grid[k][j] for k in range(9))
        if column_check:
            # 3x3宫格的行和列的起点坐标
            r, c = i // 3 * 3, j // 3 * 3
            for k in range(r, r + 3):
                for l in range(c, c + 3):
                    if grid[k][l] == value:
                        return False
            return True
    return False
使用数独板

使用以上代码生成的数独板是一个9×9的二维列表,其中0表示未填数的格子,其他数字表示已填数字的格子。可以将该列表用于游戏或其他需要数独的程序中。下面是一个简单的打印数独板的示例代码:

def print_sudoku(grid):
    for i in range(9):
        print(grid[i])
总结

数独棋盘的生成是一个基于填数和尝试的递归算法。本文通过 Python 实现了一个数独生成算法的示例,生成的数独棋盘是一个符合数独规则的有效棋盘。