在家陪上幼儿园的儿子做数学作业,其中有一个四阶数独的题目,如下。
第一次接触数独的我,被这个关于图形和数字的游戏吸引了,通过外在限制和内在逻辑推理得到结论的游戏,很适合对数字着迷的理工男。
但是毕竟四阶数独实在是太简单了。
于是我在晚上搜到了网站 https://www.sudoku-cn.com/ ,它提供标准的九阶数独题目,如下:
解题还能防脑瘫,果然是一举两得。
既然无论哪个级别的数独样子都一样(九宫格),我们就直接从“高级+”这个级别开始吧。
唯物主义者朴素的解题逻辑是这样的:
1. 为每一个空白单元格填充可能的数字。(1-9的候选数,如果不在这个单元格所在的行/列/九宫格内,那么就是这个单元格潜在的候选数字。)
2. 找到那些只有一个可行数字的单元格。
3. 找到那些在九宫格仅出现过一次的数字,这样的单元格即可确定。
4. 针对那些最新确定了唯一值的单元格,针对他们所在的行/列/九宫格,删除相同值。
5. 如上#3、#4步骤反复迭代,直到数独数据不再变化为止。
6. 如果还是不能破解,那就只能采用暴力破解法,针对多个可能数值的单元格,挨个尝试看能否找到最终解。
然而,进行到下面这样的时候,我就发现没办法继续下去了。
对于简单的数独题目,我们应该是很容易在九宫格内完成迭代收敛,但是在数独极其复杂的情况下,如上迭代可能需要重复多次,每次迭代需要遍历9*9=81个单元格,而每个单元格的数字计算需要涉及9*3-2=25个单元格,这样算起来,我的大脑内存就不够用了。
上幼儿园的儿子看着做不出题来的我,一脸关切。
于是这成了在学龄前儿童面前装逼失败被打脸的一个典范。
那可不行啊,毕竟这只是一个算力的问题,不是智力的问题。
于是,我决定写一个工具,我提供算法,工具提供颜值,计算机提供力气,然后,sudoku_solver诞生了。
先说结论,sudoku_solver是一个九阶数独解题器,长得如下样子:
我把刚才的“高级+”数独题目输进去。
点击“一键解题”。
一秒不到,解题成功。
可是,虽然数独解题成功,作为爱学习的好孩子,不教我解题方法直接告诉我一个答案算什么鬼?说好的手把手教学呢(不然我怎么知道工具是不是随便吐了个答案呢?我读书少,别骗我)。
所以我又开启了逐步解题模式,点击“设置” -> “清空”,重新输入数独数据,然后点解“下一步”按钮。
每点一下“下一步”按钮,都会显示一步操作过程,而点击“上一步”按钮还可以回溯,超级傻瓜的模式,能够展示所有的解题细节,妈妈再也不用担心我的学习了。
纳尼,不但告诉我答案,还告诉我过程,还不收费?果然是社会主义好啊!
但是等等,上面你为了演示这个题目,竟然让我输入了两遍数独题目,虽然字数也不多,可是作为懒人还是不能忍受啊。
没关系,作者在sudoku_solver的“文件”菜单栏中还加入了数独数据保存和载入功能,第一次输入数据后保存一下,后面直接载入就好了,再也不怕我的懒癌发作啦。
什么,你连一个字都不想敲,还想试试sudoku_solver的功能?果真是相当资深的程序猿啊!(对程序员而言,懒惰真是最高的美德啊)
没关系,聪明善良的作者已经考虑到了这一点,你可以在“设置”菜单栏中找到各种级别的sudoku数据,以帮助你体验sudoku_solver的解题功能,直接载入数据就可以了。
如果想对数独或者sudoku_solver有更多而了解,可以从“帮助” -> "关于Sudoku Solver"中找到更多说明信息。
我大体估算过自带的“变态”级别的数独题目,有效解题步数大约有510(不包括大量的试错步骤),按最低平均每步约9 ~ 25计算量来算,最低也有不低于5000的计算量,这还不包括中间任何一步出错就导致全盘皆错的可能性。如果按照这个估算,复杂题目纯粹靠人力分析的话... ...下周再见!
那么我该如何得到sudoku_solver呢?
github是每个程序员的最爱,你可以从 https://github.com/liyanqing1987/sudoku_solver 得到源代码。
sudoku_solver运行在Linux中,依赖python3(带pyqt5库就可以了),但是anaconda3永远是我推荐的python环境。
更多的问题,可以通过邮件随时联系作者。