首先,我想描述一个问题(它与Minesweeper非常相似)。我们给出了一个 n × m 板和一个特殊点列表( x , y ,ž)。每个点都表示围绕字段( x , y ),我们需要准确放置 z 地雷。
您还可以在此找到更好的问题描述:Prolog: where to begin solving Minesweeper-like puzzel? (它在prolog中,但不关心编程语言)
我们的任务是生成满足任务条件的所有可能的板。
例如:
让n = 3
,m = 3
和L = [(2,2,1)]
列为特殊点,因此可能的解决方案是:
[[' ', ' ', ' '], [' ', 1, ' '], [' ', ' ', *]]
其中''是空格,'*'是我的。
我想在Haskell中找到一些有用的想法来编写这个问题。我唯一的想法是生成所有可能的设置地雷组合或使用回溯,但我发现很难在haskell中实现。
任何想法怎么做?
答案 0 :(得分:5)
使用list monad在Haskell中回溯非常简单。这是一个例子:
import Control.Monad (guard)
pairs :: [(Int,Int)]
pairs = do
x <- [1..10]
y <- [1..x]
guard (even (x + y))
return (x,y)
将为您提供所有(x,y)
对,y <= x
和x + y
为偶数。
所以你会想要像
这样的东西type Board = ...
insertMine :: (Int,Int) -> Board -> [Board]
-- return all ways of inserting a mine adjacent to the given coordinate
insertMines :: (Int,Int) -> Board -> [Board]
insertMines p board = do
b1 <- insertMine p board
b2 <- insertMine p b1
b3 <- insertMine p b2
return b3
有很多方法可以使这更简单,更抽象,但我试图在我认为是你的水平附近举一个例子。通过列表monad回溯是一个很好的方式来适应monad!