指导DeepSeek用优化的思路实现的数独生成器

前面让DeepSeek独立自主做了一个数独生成器,它生成大的数独效率较低,观察如下结果:

 1  2  3  4  5  6  7  8  9
 4  5  6  7  8  9  1  2  3
 7  8  9  1  2  3  4  5  6
 2  1  4  3  6  5  8  9  7
 3  6  5  8  9  7  2  1  4
 8  9  7  2  1  4  3  6  5
 5  3  1  6  4  2  9  7  8
 6  4  2  9  7  8  5  3  1
 9  7  8  5  3  1  6  4  2

把数字3个一组顺序编排,可以生成有规律的数独答案,在此基础上,交换组内的行不影响结果,比如1、2行互换,仍然是有效的。如下所示:

4  5  6  7  8  9  1  2  3
1  2  3  4  5  6  7  8  9 
7  8  9  1  2  3  4  5  6
2  1  4  3  6  5  8  9  7
3  6  5  8  9  7  2  1  4
8  9  7  2  1  4  3  6  5
5  3  1  6  4  2  9  7  8
6  4  2  9  7  8  5  3  1
9  7  8  5  3  1  6  4  2

交换组内的列也是如此,依据此思路,随机交换几次行列,再随机去掉多余的数来生成数独题目。16x16则4个一组(即一个宫)。

让DeepSeek按照上述思路重新编写,一举成功。

import random
import csv

def generate_sudoku_template(n):
    box_size = int(n ** 0.5)
    grid = [[0 for _ in range(n)] for _ in range(n)]
    
    for i in range(n):
        for j in range(n):
            grid[i][j] = (i * box_size + i // box_size + j) % n + 1
    
    return grid

def shuffle_grid(grid, n, shuffle_times=10):
    box_size = int(n ** 0.5)
    
    for _ in range(shuffle_times):
        # 交换组内的行
        block = random.randint(0, box_size - 1)
        row1 = random.randint(0, box_size - 1)
        row2 = random.randint(0, box_size - 1)
        r1 = block * box_size + row1
        r2 = block * box_size + row2
        grid[r1], grid[r2] = grid[r2], grid[r1]
        
        # 交换组内的列
        block = random.randint(0, box_size - 1)
        col1 = random.randint(0, box_size - 1)
        col2 = random.randint(0, box_size - 1)
        c1 = block * box_size + col1
        c2 = block * box_size + col2
        for i in range(n):
            grid[i][c1], grid[i][c2] = grid[i][c2], grid[i][c1]
    
    return grid

def create_puzzle(grid, n, q):
    total_cells = n * n
    if q > total_cells:
        q = total_cells
    
    puzzle = [[grid[i][j] for j in range(n)] for i in range(n)]
    positions = [(i, j) for i in range(n) for j in range(n)]
    random.shuffle(positions)
    
    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, 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 = 9
    q = 30
    char_type = 'upper'
    
    template = generate_sudoku_template(n)
    shuffled = shuffle_grid(template, n, shuffle_times=20)
    puzzle = create_puzzle(shuffled, n, q)
    save_sudoku(puzzle, n, char_type, 'sudoku.csv', 'sudoku.txt')

以下是它生成的16x16(30)的数独,DLX程序求解结果随后,所以它是有效的。

---N--------L---
-----F--------O-
-------L---P-A--
LI--------------
----------------
-----------M----
--H---L-----E---
-N-------F-I---K
--------D-------
B--P------------
--------P-------
F---G-----------
----L--O--------
--------I-------
----P-B-----K---
----------N-----

EPFNAHGBJMIOLKCD
HCJDIFMPLNKABGOE
KGBMNCOLFDEPJAHI
LIAOEDJKCHBGFPNM
DKCAFINMOPJEHLBG
OJGBKPHENLAMIFDC
MFHIOJLGKCDBENPA
PNLECBDAHFGIMOJK
NEIGMLPJDAFCOBKH
BLOPDKCIEGHNAJMF
AMKCBOFHPILJDEGN
FHDJGEANMBOKPCIL
CDNKLMIOAJPFGHEB
JBPLHGKFIECDNMAO
IAEFPNBCGOMHKDLJ
GOMHJAEDBKNLCIFP

以上程序生成最大的数独支持到49x49,更大的无法用大小写字母数字字符表示了。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值