因为要测试数据求解器,需要造一些数据来测试,因此让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----------------


被折叠的 条评论
为什么被折叠?



