読者です 読者をやめる 読者になる 読者になる

すごいH本のチェスの演習問題書いた

「すごいHaskellたのしく学ぼう!」の308ページの、3手で到達できるときその途中経路を出力する演習問題を書いてみた

import Control.Monad

type Route = [(Int, Int)]

routeStart :: (Int, Int) -> Route
routeStart x = [x]

inBoard :: Route -> Bool 
inBoard (x:xs) = x `elem` [(a,b) | a <- [1..8], b <- [1..8]]

possibleRoute :: Route -> [Route]
possibleRoute all@((x,y):xs) = do
  (dx,dy) <- [(2,1), (-2,1), (2,-1), (-2,-1), (1,2), (1,-2), (-1,2), (-1,-2)]
  let p = (x+dx, y+dy)
      r = p:all
  guard $ inBoard r
  return r

canReachIn3 :: (Int, Int) -> (Int, Int) -> [Route]
canReachIn3 s g = filter (\x -> head x == g)
                  (return (routeStart s) >>= possibleRoute >>= possibleRoute
                  >>= possibleRoute)