Haskell杀手数独求解器挂起问题排查求助
Haskell杀手数独求解器挂起问题排查求助
之前我用Haskell写过一个数独求解器,和很多人一样,这是个挺不错的练手项目。它采用简单的暴力算法:找到一个空单元格(如果没有空单元格,就说明谜题已经解出来了),确定这个空单元格能填哪些值,然后对每个可能的值填入单元格,递归求解新生成的网格。这个求解器运行得相当不错,解2012年号称最难数独的谜题只需要大概3秒。
因为我平时喜欢玩杀手数独,所以后来就琢磨着把这个求解器扩展成也能解杀手数独的版本。如果你不了解这个变种规则,我简单说明下:杀手数独的网格会被划分成不同的区域,每个区域包含2到9个单元格,还对应一个总和。合法的解要求每个区域内的单元格数值都不重复,且加起来等于该区域的总和。除此之外,普通数独的规则依然完全适用——1到9每个数字在每行、每列、每个3x3小九宫格都只能出现一次;而且因为区域带来的额外约束信息,杀手数独的初始网格不需要预先填入部分答案。
我实现扩展的方式是让原本解普通数独的算法支持多态,这样就能同时适配普通数独和杀手数独。核心的改动点在于:计算某个空单元格的可填数值时,除了要考虑行、列、九宫格的约束,还要加入该单元格所属区域的约束。
我已经单独测试了解决方案里的每一个函数,看起来都能正常工作;但当我用它解一个杀手数独示例的时候,程序却一直不终止,我完全搞不懂原因。不过解普通数独的时候还是能正常完成的。所以我有两个问题想请教大家:
- 我的代码里有没有什么我没察觉到的问题,导致求解器挂起?
- 我可以使用哪些工具来检查代码的执行过程,找出导致挂起的根源?
补充一下我的运行方式:我把代码文件加载到ghci中,然后运行以下命令之一:
sudoku puzzle:用来求解普通数独sudoku killerPuzzle:用来求解杀手数独
备注:内容来源于stack exchange,提问作者Jeremy Hicks
相关产品推荐
相关产品推荐

