DeepSeek辅助编写的简易数独生成器

因为要测试数据求解器,需要造一些数据来测试,因此让DeepSeek编写一个数独生成器。
需求是:指定行列数(行数列数相同)n,已知格子数q,生成 数字csv和字符两种格式,字符可选纯数字、数字+大写,数字+大小写,视n而定,只需要给出程序,不做别的。
因为是随机生成每行,效率不太高,生成25x25数独还可以,36x36就不行了。

import random
import csv

def generate_sudoku(n, q, char_type='digit'):
    total_cells = n * n
    if q > total_cells:
        q = total_cells
    
    # 生成完整数独解
    grid = [[0 for _ in range(n)] for _ in range(n)]
    
    def is_valid(row, col, num):
        # 检查行
        for i in range(n):
            if grid[row][i] == num:
                return False
        
        # 检查列
        for i in range(n):
            if grid[i][col] == num:
                return False
        
        # 检查宫格(如果适用)
        box_size = int(n ** 0.5)
        if box_size * box_size == n:
            start_row, start_col = row - row % box_size, col - col % box_size
            for i in range(box_size):
                for j in range(box_size):
                    if grid[start_row + i][start_col + j] == num:
                        return False
        return True
    
    def solve():
        for row in range(n):
            for col in range(n):
                if grid[row][col] == 0:
                    nums = list(range(1, n + 1))
                    random.shuffle(nums)
                    for num in nums:
                        if is_valid(row, col, num):
                            grid[row][col] = num
                            if solve():
                                return True
                            grid[row][col] = 0
                    return False
        return True
    
    # 生成完整解
    solve()
    
    # 挖空
    positions = [(i, j) for i in range(n) for j in range(n)]
    random.shuffle(positions)
    
    puzzle = [[grid[i][j] for j in range(n)] for i in range(n)]
    for i in range(total_cells - q):
        row, col = positions[i]
        puzzle[row][col] = 0
    
    return puzzle

def convert_to_char(num, n, char_type):
    if num == 0:
        return '-'
    
    if char_type == 'digit':
        return str(num)
    elif char_type == 'upper':
        if num <= 26:
            return chr(num - 1 + ord('A'))
        else:
            return str(num)
    elif char_type == 'mixed':
        if num <= 26:
            return chr(num - 1 + ord('A'))
        elif num <= 52:
            return chr(num - 27 + ord('a'))
        else:
            return str(num)

def save_sudoku(puzzle, n, q, char_type, csv_filename, txt_filename):
    # 保存CSV格式
    with open(csv_filename, 'w', newline='') as csvfile:
        writer = csv.writer(csvfile)
        for row in puzzle:
            csv_row = []
            for num in row:
                if num == 0:
                    csv_row.append('*')
                else:
                    csv_row.append(str(num))
            writer.writerow(csv_row)
    
    # 保存字符格式
    with open(txt_filename, 'w') as txtfile:
        for row in puzzle:
            char_row = []
            for num in row:
                char_row.append(convert_to_char(num, n, char_type))
            txtfile.write(''.join(char_row) + '\n')

if __name__ == "__main__":
    n = 25
    q = 100
    char_type = 'upper'
    
    puzzle = generate_sudoku(n, q)
    save_sudoku(puzzle, n, q, char_type, 'sudoku25.csv', 'sudoku25.txt')

生成的数独格式如下,可以用上文的程序来求解。

--Y---E-------B------S---
-----M----------CS-------
Q-----------------F--K---
-S---G-U-----------------
-------P--------X----H-A-
G----HM------I----------D
----W--Y-----L-M---------
----------AY-----N---V---
---EY-----------P---T----
-----D---O---W-----B-----
---M-----Q---------------
------------QT---VS------
-----IX----JK------------
-------A--D----XQ--R-----
X--K------F--------U--H--
--A-H-GJ------F----X-D---
--------N-----L----------
-----------CJS-----------
-----R--------A-------I--
------D-----E--G---------
P-D-G---------J----------
J----XC--E-----BDYP---V--
-------WDUIV--G---M------
---U------------------B--
-------GO----------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值