为一个作业制作一个数独求解器,我在解决数独的空白单元格时遇到了问题。我可以轻松地使用独特的解决方案来解决单元格,但是当我遇到具有多个解决方案的单元格时(在数独的当前状态下),我想继续下一个空白以尝试尽可能多地填充数据,然后再尝试“相应的价值观和分支我的解决方案。
我的问题是我不知道如何跟踪我所处的空白值。
blank :: Sudoku -> Pos
blank sudoku
| elem '.' $ toString sudoku = ( (positInRow `div` 9), (positInRow `mod` 9) )
| otherwise = error "no blanks"
where
positInRow = fromJust $ elemIndex '.' $ toString sudoku
nextBlank :: Sudoku -> Pos -> Pos
nextBlank sudoku (x, y)
| elem '.' $ drop (x*9+y) $ toString sudoku = blank (fromString $ drop (x*9+y) $ toString sudoku)
| otherwise = error "no blanks"
这是我尝试过的解决方案,但是如果我尝试以递归方式解决数独游戏,那么如果原始的下一个空白没有更新数独的值,它将陷入无限循环,找到相同的“nextBlank”。
有没有办法正确实现这个功能?
答案 0 :(得分:1)
首先让我将你的代码包装在一些样板文件中,这样我们就可以运行了 容易的事情:
module RandomNoise where
import Data.Maybe
import Data.List
type Pos = (Int, Int)
type Sudoku = String
toString :: Sudoku -> String
toString = id
fromString :: String -> Sudoku
fromString = id
blank :: Sudoku -> Pos
blank sudoku
| elem '.' $ toString sudoku = (positInRow `div` 9, positInRow `mod` 9)
| otherwise = error "no blanks"
where
positInRow = fromJust $ elemIndex '.' $ toString sudoku
nextBlank :: Sudoku -> Pos -> Pos
nextBlank sudoku (x, y)
| elem '.' $ drop (x*9+y) $ toString sudoku = blank (fromString $ drop (x*9+y) $ toString sudoku)
| otherwise = error "no blanks"
testSudoku = "uiae.uiae.uiae.uiae"
firstBlank = blank testSudoku
secondBlankOrNot = nextBlank testSudoku firstBlank
如果您启动ghci并加载包含该内容的文件, 你可以看到,
firstBlank = (0,4)
secondBlank = (0,0)
和
drop (0*9+4) testSudoku
产量
".uiae.uiae.uiae"
所以这里有几个问题。