Skip to content

Instantly share code, notes, and snippets.

@RoryDungan
Last active December 10, 2017 06:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RoryDungan/f0e91d6ed907b09f4ed69f2a77de1645 to your computer and use it in GitHub Desktop.
Save RoryDungan/f0e91d6ed907b09f4ed69f2a77de1645 to your computer and use it in GitHub Desktop.
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 = do
first <- moveKnight start
second <- moveKnight first
moveKnight second
canReachIn3 :: KnightPos -> KnightPos -> Bool
canReachIn3 start end = end `elem` in3 start
canReachInX :: Int -> KnightPos -> KnightPos -> Bool
canReachInX x start end = end `elem` inX x start
inX :: Int -> KnightPos -> [KnightPos]
inX x = foldr (<=<) return $ replicate x moveKnight
in3Path :: KnightPos -> [[KnightPos]]
in3Path start = do
first <- moveKnight start
second <- moveKnight first
third <- moveKnight second
return [first, second, third]
canReachIn3Path :: KnightPos -> KnightPos -> Maybe [KnightPos]
canReachIn3Path start end =
let paths = in3Path start
path = filter ((end ==) . last) paths
in if null path then Nothing else Just $ head path
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment