用haskell实现的八皇后程序

用Haskell解八皇后问题,Haskell才是最精练的程序:

main  = print $ queens 8

boardSize = 8

queens 0 = [[]]
queens n = [ x : y | y <- queens (n-1), x <- [1..boardSize], safe x y 1]
      where
         safe x [] n = True
         safe x (c:y) n = and [ x /= c , x /= c + n , x /= c - n , safe x y (n+1)]

运行结果:

[[4,2,7,3,6,8,5,1],[5,2,4,7,3,8,6,1],[3,5,2,8,6,4,7,1],[3,6,4,2,8,5,7,1],[5,7,1,3,8,6,4,2],[4,6,8,3,1,7,5,2]  ... ... ... ... 5,7,2,6,3,1,4,8]]

 

另外一种用到了monad的源程序:

import Control.Monad
 
queens n = foldM (\y _ -> [ x : y | x <- [1..n], safe x y 1]) [] [1..n]
safe x [] n = True
safe x (c:y) n = and [ x /= c , x /= c + n , x /= c - n , safe x y (n+1)]
 
main = mapM_ print $ queens 8

运行结果:

[4,2,7,3,6,8,5,1]

[5,2,4,7,3,8,6,1]

[3,5,2,8,6,4,7,1]

… … … …

[5,7,2,6,3,1,4,8]

 

albertlee在这篇用 Python 秒掉八皇后问题!中给出的haskell程序:

import Control.Monad
import Control.Monad.Writer
import Data.List

diagonal (x1,y1) (x2,y2) = x1 + y1 == x2 + y2
                        || x1 - y1 == x2 - y2

nqueens n = execWriter $ f [1..n] 1 []
    where f [] _ ps = tell [ps]
          f cs r ps = forM_ cs $ \c ->;
                          unless (any (diagonal (r,c)) ps) $
                              f (delete c cs) (r + 1) ((r,c):ps)
main = print $ nqueens 4

http://fleurer-lee.com/2009/04/03/haskellqiu-jie-nhuang-hou-wen-ti.html给出的代码:

module Main where
import Data.List

queue :: Int -> Int -> [[Int]]
queue m 1 = [ [x] | x  <- [1..m] ]
queue m n = concatMap put $ filter putable $ queue m (n-1)
    where
        putable xs = (safe_places xs /= [])
        put xs = map (:xs) $ safe_places xs
        safe_places xs = [1..m] \\ (concatMap (\(x,y) -> [x-y,x,x+y]) $ zip xs [1..])

 

下面这个网址给出了另外一种解法,并且有详细的解释:

http://blog.chinaunix.net/uid-8582194-id-374620.html

main = do
    putStrLn $ "There are " ++ show(length result) ++ " solutions in total"
    mapM_ (print.zipWith (\x y -> x:show y) ['A'..'H']) result
    where
        result = queens 8

queens 0 = [[]]
queens n = [ q:b | b <- queens (n-1), q <- [1..8], safe q b ]
safe q b = and [ not (checks q b i) | i <- [0..(length b-1)] ]
checks q b i = q==b!!i || abs(q - b!!i)==i+1

Haskell了解得还太少,暂时这些代码都看不懂,先收集在这里,以后慢慢理解。

posted @ 2012-10-06 11:16  申龙斌的程序人生  阅读(2197)  评论(0编辑  收藏  举报