I'm new in the Haskell world, and probably my question is a silly one, but I just can't understand the behavior of ghci or ghc in this situation.
I tried to solve the old "Knights_Tour" problem from 99-questions on haskell.org, and the solution I found just works fine till 61 moves (a total of 62 positions, missing the total just by 2 positions). However, if I increase the total moves to 63 ghci or runhaskell or the compiled program just stop working without a answer after a minute or more.
The program:
import Control.Monad (guard)
type Position = (Int, Int)
type Positions = [Position]
moveKnight :: Positions -> [Positions]
moveKnight pos@((col, row):xs) = do
(col', row') <- [(col+2, row-1), (col+2, row+1), (col-2, row-1), (col-2, row+1),
(col+1, row-2), (col+1, row+2), (col-1, row-2), (col-1, row+2)]
guard (col' `elem` [1..8] && row' `elem` [1..8] && (not . (`elem` pos)) (col', row'))
return ((col', row'):pos)
moveMany :: Int -> Position -> [Positions]
moveMany moves start = return (return start) >>= foldr (<=<) return (replicate moves moveKnight)
getMoves :: Position -> [Positions]
getMoves start = moveMany 63 start
I recognize the answer is not well ordered (a missing reverse, but it dont change the total behavior). When I do "head $ getMoves (1,1)" with 61 moves I get an answer in 0.23 secs, but with 63 moves no answer at all. Can anyone explain to me why this don't work, and some workaround for this situation? and why the other solutions (like the ones from 99-questions page) work fine??
NOTE: I tried a different moveMany function but just gained 1 more move (62, just 1 move away...)
moveMany' :: Int -> Position -> [Positions]
moveMany' moves start = tour moves (return (return start))
where tour 1 pos = pos
tour n pos = tour (n - 1) (pos >>= moveKnight)