0

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) 

1 Answers1

0
run :: Int -> [Positions] -> IO ()
run 0 _ = putStrLn "Stopping"
run n pos = do
  let pos' = pos >>= moveKnight
  print $ length pos'
  run (n-1) pos'

Try running this. It might clear things up. There is nothing fancy going on here, really.

Karolis Juodelė
  • 3,708
  • 1
  • 19
  • 32
  • Thanks a lot @Karolis but... after 10 cycles my system almost crashed :) ghc reached 1.94G of memory... – Sérgio Paulo Oct 07 '13 at 22:53
  • That's the point. You are trying to do a ridiculous amount of computation. Apparently in your case until 61 steps only the first few possibilities need to be computed but at 63 steps most of them are processed. This is what you get for using brute force algorithms. – Karolis Juodelė Oct 08 '13 at 05:14
  • and how do you think I can modify my code to work farter? Through my newbie goggles the solution on 99-questions page dont seams much different from my aproach... – Sérgio Paulo Oct 08 '13 at 09:00
  • [Wikipedia](http://en.wikipedia.org/wiki/Knight's_tour#Finding_tours_with_computers) has a few suggestions for it. Don't expect to find a simple solution though. – Karolis Juodelė Oct 08 '13 at 16:38