目标是在 Python 中创建一个 9x9 的数独矩阵。
所以我走到了这一步。但我似乎无法获得使内部特遣队箱正确的程序。
def sudoku(size):
import random as rn
mydict = {}
n = 0
while len(mydict) < 9:
n += 1
x = range(1, size+1)
testlist = rn.sample(x, len(x))
isgood = True
for dictid,savedlist in mydict.items():
if isgood == False:
break
for v in savedlist:
if testlist[savedlist.index(v)] == v:
isgood = False
break
if isgood == True:
#print 'success', testlist
mydict[len(mydict)] = testlist
return mydict, n
return_dict, total_tries = sudoku(9)
for n,v in return_dict.items():
print n,v
print 'in',total_tries,'tries'
原文由 Justin Malinchak 发布,翻译遵循 CC BY-SA 4.0 许可协议
您可以生成一个随机数独解决方案板,其中填写了所有数字,然后删除其中一些以创建拼图。这将确保拼图始终有解决方案。确保它只有一个解决方案更具挑战性(提示:您必须为 9x9 数独保留至少 17 个数字)
下面的算法将立即为 N < 1000 生成一个 NxN 随机数独解决方案板。
然后,您可以从数独解决方案中删除一些数字来创建拼图:
对于 4x4 到 36x36 的拼图,您可以像这样打印出更好的棋盘:
[编辑]
这里有一些关于洗牌过程的额外信息……
洗牌行分为 3 行一组。可以将组作为一个整体交换,但我们不能在不破坏块完整性的情况下跨组交换行。 (同样的推理适用于列)
例如:
我们可以通过同时移动所有 3 行来交换组 0、1、2:
我们可以在一组的 3 行之间交换(例如 3、4、5)…
我们不能跨组交换行(例如 1 <–> 3):
查看左上角块中的重复 8,下面的重复 7,等等。
单解谜题
为了生成只有一个解决方案的数独游戏,您需要一个求解器函数,它可以告诉您是否有多个解决方案。我建议的策略是从删除 75%(或更多)的数字开始,然后检查是否只有一个解决方案。如果有不止一种解决方案,请放回一个数字并再次检查。您可以在随机位置放回一个数字或选择解决方案不同的位置(这将更快地收敛到单个解决方案难题)
首先编写一个求解器,它将生成它找到的所有解(理想情况下作为生成器,因为我们只需要前 2 个)。这是一个简单的:
从
solution
包含所有数字的变量和board
包含已清除 3⁄4 数字的谜题的变量开始,您可以将数字添加回棋盘,直到只有一种方法可以解决这个问题:输出:
请注意,对于 9x9 数独板,这将在合理的时间内工作,但对于更大的板,您将需要更好/更快的求解器功能
另请注意,这通常会产生“简单”的谜题,因为在某些情况下它会添加比绝对必要的更多的数字。选择最小的数字集以添加回溯将需要分层或回溯方法,这会稍微复杂一些并且运行起来要慢得多。从更多的空白空间开始(例如 80% 或更多)将很有可能在合理的时间范围内制作出更难的谜题。