【Haskell】 H本 13.6のチェスの演習問題
環境 ghc 7.8.3 CentOS7.0
「すごいHaskellたのしく学ぼう!」第13章 メモ
13.6のチェスの演習問題をやってみた。
import Control.Monad type KnightPos = (Int, Int) -- (横, 縦) moveKnight :: KnightPos -> [KnightPos] moveKnight (c,r) = do (c', r') <- [(c+2,r-1),(c+2,r+1),(c-2,r-1),(c-2,r+1) ,(c+1,r-2),(c+1,r+2),(c-1,r-2),(c-1,r+2) ] guard (c' `elem` [1..8] && r' `elem` [1..8]) return (c', r') in3 :: KnightPos -> [KnightPos] in3 start = return start >>= moveKnight >>= moveKnight >>= moveKnight canReachIn3 :: KnightPos -> KnightPos -> Bool canReachIn3 start end = end `elem` in3 start -- ----------------- -- ここまで本と同じ -- ----------------- type KnightRoute = [KnightPos] routeKnight :: KnightRoute -> [KnightRoute] routeKnight rt = return rt >>= (\x -> moveKnight $ head x) >>= \next -> [next:rt] routeIn3 :: KnightPos -> [KnightRoute] routeIn3 pos = return [pos] >>= routeKnight >>= routeKnight >>= routeKnight reachRouteIn3 :: KnightPos -> KnightPos -> [KnightRoute] reachRouteIn3 start end = reverse $ filter (\x -> end == head x) $ routeIn3 start
ghci> reachRouteIn3 (1,1) (3,2) [[(3,2),(1,1),(2,3),(1,1)], [(3,2),(4,4),(2,3),(1,1)], [(3,2),(2,4),(3,2),(1,1)], [(3,2),(4,4),(3,2),(1,1)], [(3,2),(1,3),(3,2),(1,1)], [(3,2),(1,1),(3,2),(1,1)], [(3,2),(5,3),(3,2),(1,1)], [(3,2),(5,1),(3,2),(1,1)] ] ghci> reachRouteIn3 (1,1) (7,4) [[(7,4),(5,3),(3,2),(1,1)]] ghci> reachRouteIn3 (1,1) (8,8) []