Python 数独程序未生成结果
Python Sudoku program not generating results
我一直在尝试编写一个生成数独谜题的程序,但我的程序似乎无法运行。由于我的 4X4 能够生成结果,因此该程序似乎花费了 运行 太长的时间。插入的 2 个打印语句确实在打印“1”和“2”。
import random
board = []
for nine in range(9):
board.append([0, 0, 0, 0, 0, 0, 0, 0, 0])
def sudoku():
for index in range(81):
row = index // 9
col = index % 9
while board[row][col] == 0:
chosen = random.randint(1, 9)
print(1)
if chosen not in board[row]:
if check_col(col, chosen) != 1:
if row < 3:
if col < 3:
if check_square(0, 0, chosen) != 1:
board[row][col] = chosen
elif col < 6:
if check_square(0, 3, chosen) != 1:
board[row][col] = chosen
else:
if check_square(0, 6, chosen) != 1:
board[row][col] = chosen
print(2)
elif row < 6:
if col < 3:
if check_square(3, 0, chosen) != 1:
board[row][col] = chosen
elif col < 6:
if check_square(3, 3, chosen) != 1:
board[row][col] = chosen
else:
if check_square(3, 6, chosen) != 1:
board[row][col] = chosen
else:
if col < 3:
if check_square(6, 0, chosen) != 1:
board[row][col] = chosen
elif col < 6:
if check_square(6, 3, chosen) != 1:
board[row][col] = chosen
else:
if check_square(6, 6, chosen) != 1:
board[row][col] = chosen
def check_col(col, chosen):
check = 0
for c_row in range(9):
if chosen == board[c_row][col]:
check = 1
return check
def check_square(starting_row, starting_col, chosen):
check = 0
for c_add in range(3):
if chosen in board[starting_row + c_add][starting_col:starting_col + 3]:
check = 1
return check
sudoku()
for printing in range(9):
print(board[printing])
您可以生成一个随机的数独解决方案板,其中填写了所有数字,然后删除其中一些以创建拼图。这将确保拼图始终有解决方案。确保它只有一个解决方案更具挑战性(提示:您必须为 9x9 数独保留至少 17 个数字)
下面的算法将立即生成一个 NxN 的随机数独答案板,N < 1000。
base = 3
side = base*base
# pattern for a baseline valid solution
def pattern(r,c): return (base*(r%base)+r//base+c)%side
# randomize rows, columns and numbers (of valid base pattern)
from random import sample
def shuffle(s): return sample(s,len(s))
rBase = range(base)
rows = [ g*base + r for g in shuffle(rBase) for r in shuffle(rBase) ]
cols = [ g*base + c for g in shuffle(rBase) for c in shuffle(rBase) ]
nums = shuffle(range(1,base*base+1))
# produce board using randomized baseline pattern
board = [ [nums[pattern(r,c)] for c in cols] for r in rows ]
for line in board: print(line)
[6, 2, 5, 8, 4, 3, 7, 9, 1]
[7, 9, 1, 2, 6, 5, 4, 8, 3]
[4, 8, 3, 9, 7, 1, 6, 2, 5]
[8, 1, 4, 5, 9, 7, 2, 3, 6]
[2, 3, 6, 1, 8, 4, 9, 5, 7]
[9, 5, 7, 3, 2, 6, 8, 1, 4]
[5, 6, 9, 4, 3, 2, 1, 7, 8]
[3, 4, 2, 7, 1, 8, 5, 6, 9]
[1, 7, 8, 6, 5, 9, 3, 4, 2]
然后您可以从数独解决方案中删除一些数字来创建拼图:
squares = side*side
empties = squares * 3//4
for p in sample(range(squares),empties):
board[p//side][p%side] = 0
numSize = len(str(side))
for line in board: print("["+" ".join(f"{n or '.':{numSize}}" for n in line)+"]")
[6 . . . . 3 . . 1]
[. 9 . . . . . . 3]
[4 . 3 . . . 6 . .]
[. . . 5 9 . 2 . 6]
[. . . . . . . . .]
[. . 7 . . . . . 4]
[. . . . . . 1 7 .]
[. . 2 . . 8 . . .]
[. . 8 . . . . 4 2]
对于 4x4 到 36x36 的拼图,您可以像这样打印出更好的棋盘:
def expandLine(line):
return line[0]+line[5:9].join([line[1:5]*(base-1)]*base)+line[9:13]
line0 = expandLine("╔═══╤═══╦═══╗")
line1 = expandLine("║ . │ . ║ . ║")
line2 = expandLine("╟───┼───╫───╢")
line3 = expandLine("╠═══╪═══╬═══╣")
line4 = expandLine("╚═══╧═══╩═══╝")
symbol = " 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
nums = [ [""]+[symbol[n] for n in row] for row in board ]
print(line0)
for r in range(1,side+1):
print( "".join(n+s for n,s in zip(nums[r-1],line1.split("."))) )
print([line2,line3,line4][(r%side==0)+(r%base==0)])
╔═══╤═══╤═══╦═══╤═══╤═══╦═══╤═══╤═══╗
║ 6 │ │ ║ │ │ 3 ║ │ │ 1 ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ 9 │ ║ │ │ ║ │ │ 3 ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ 4 │ │ 3 ║ │ │ ║ 6 │ │ ║
╠═══╪═══╪═══╬═══╪═══╪═══╬═══╪═══╪═══╣
║ │ │ ║ 5 │ 9 │ ║ 2 │ │ 6 ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ │ ║ │ │ ║ │ │ ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ │ 7 ║ │ │ ║ │ │ 4 ║
╠═══╪═══╪═══╬═══╪═══╪═══╬═══╪═══╪═══╣
║ │ │ ║ │ │ ║ 1 │ 7 │ ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ │ 2 ║ │ │ 8 ║ │ │ ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ │ 8 ║ │ │ ║ │ 4 │ 2 ║
╚═══╧═══╧═══╩═══╧═══╧═══╩═══╧═══╧═══╝
我一直在尝试编写一个生成数独谜题的程序,但我的程序似乎无法运行。由于我的 4X4 能够生成结果,因此该程序似乎花费了 运行 太长的时间。插入的 2 个打印语句确实在打印“1”和“2”。
import random
board = []
for nine in range(9):
board.append([0, 0, 0, 0, 0, 0, 0, 0, 0])
def sudoku():
for index in range(81):
row = index // 9
col = index % 9
while board[row][col] == 0:
chosen = random.randint(1, 9)
print(1)
if chosen not in board[row]:
if check_col(col, chosen) != 1:
if row < 3:
if col < 3:
if check_square(0, 0, chosen) != 1:
board[row][col] = chosen
elif col < 6:
if check_square(0, 3, chosen) != 1:
board[row][col] = chosen
else:
if check_square(0, 6, chosen) != 1:
board[row][col] = chosen
print(2)
elif row < 6:
if col < 3:
if check_square(3, 0, chosen) != 1:
board[row][col] = chosen
elif col < 6:
if check_square(3, 3, chosen) != 1:
board[row][col] = chosen
else:
if check_square(3, 6, chosen) != 1:
board[row][col] = chosen
else:
if col < 3:
if check_square(6, 0, chosen) != 1:
board[row][col] = chosen
elif col < 6:
if check_square(6, 3, chosen) != 1:
board[row][col] = chosen
else:
if check_square(6, 6, chosen) != 1:
board[row][col] = chosen
def check_col(col, chosen):
check = 0
for c_row in range(9):
if chosen == board[c_row][col]:
check = 1
return check
def check_square(starting_row, starting_col, chosen):
check = 0
for c_add in range(3):
if chosen in board[starting_row + c_add][starting_col:starting_col + 3]:
check = 1
return check
sudoku()
for printing in range(9):
print(board[printing])
您可以生成一个随机的数独解决方案板,其中填写了所有数字,然后删除其中一些以创建拼图。这将确保拼图始终有解决方案。确保它只有一个解决方案更具挑战性(提示:您必须为 9x9 数独保留至少 17 个数字)
下面的算法将立即生成一个 NxN 的随机数独答案板,N < 1000。
base = 3
side = base*base
# pattern for a baseline valid solution
def pattern(r,c): return (base*(r%base)+r//base+c)%side
# randomize rows, columns and numbers (of valid base pattern)
from random import sample
def shuffle(s): return sample(s,len(s))
rBase = range(base)
rows = [ g*base + r for g in shuffle(rBase) for r in shuffle(rBase) ]
cols = [ g*base + c for g in shuffle(rBase) for c in shuffle(rBase) ]
nums = shuffle(range(1,base*base+1))
# produce board using randomized baseline pattern
board = [ [nums[pattern(r,c)] for c in cols] for r in rows ]
for line in board: print(line)
[6, 2, 5, 8, 4, 3, 7, 9, 1]
[7, 9, 1, 2, 6, 5, 4, 8, 3]
[4, 8, 3, 9, 7, 1, 6, 2, 5]
[8, 1, 4, 5, 9, 7, 2, 3, 6]
[2, 3, 6, 1, 8, 4, 9, 5, 7]
[9, 5, 7, 3, 2, 6, 8, 1, 4]
[5, 6, 9, 4, 3, 2, 1, 7, 8]
[3, 4, 2, 7, 1, 8, 5, 6, 9]
[1, 7, 8, 6, 5, 9, 3, 4, 2]
然后您可以从数独解决方案中删除一些数字来创建拼图:
squares = side*side
empties = squares * 3//4
for p in sample(range(squares),empties):
board[p//side][p%side] = 0
numSize = len(str(side))
for line in board: print("["+" ".join(f"{n or '.':{numSize}}" for n in line)+"]")
[6 . . . . 3 . . 1]
[. 9 . . . . . . 3]
[4 . 3 . . . 6 . .]
[. . . 5 9 . 2 . 6]
[. . . . . . . . .]
[. . 7 . . . . . 4]
[. . . . . . 1 7 .]
[. . 2 . . 8 . . .]
[. . 8 . . . . 4 2]
对于 4x4 到 36x36 的拼图,您可以像这样打印出更好的棋盘:
def expandLine(line):
return line[0]+line[5:9].join([line[1:5]*(base-1)]*base)+line[9:13]
line0 = expandLine("╔═══╤═══╦═══╗")
line1 = expandLine("║ . │ . ║ . ║")
line2 = expandLine("╟───┼───╫───╢")
line3 = expandLine("╠═══╪═══╬═══╣")
line4 = expandLine("╚═══╧═══╩═══╝")
symbol = " 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
nums = [ [""]+[symbol[n] for n in row] for row in board ]
print(line0)
for r in range(1,side+1):
print( "".join(n+s for n,s in zip(nums[r-1],line1.split("."))) )
print([line2,line3,line4][(r%side==0)+(r%base==0)])
╔═══╤═══╤═══╦═══╤═══╤═══╦═══╤═══╤═══╗
║ 6 │ │ ║ │ │ 3 ║ │ │ 1 ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ 9 │ ║ │ │ ║ │ │ 3 ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ 4 │ │ 3 ║ │ │ ║ 6 │ │ ║
╠═══╪═══╪═══╬═══╪═══╪═══╬═══╪═══╪═══╣
║ │ │ ║ 5 │ 9 │ ║ 2 │ │ 6 ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ │ ║ │ │ ║ │ │ ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ │ 7 ║ │ │ ║ │ │ 4 ║
╠═══╪═══╪═══╬═══╪═══╪═══╬═══╪═══╪═══╣
║ │ │ ║ │ │ ║ 1 │ 7 │ ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ │ 2 ║ │ │ 8 ║ │ │ ║
╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
║ │ │ 8 ║ │ │ ║ │ 4 │ 2 ║
╚═══╧═══╧═══╩═══╧═══╧═══╩═══╧═══╧═══╝