8
\$\begingroup\$

Of course the recursive version is trivial:

hanoi n = solve n 1 2 3
solve 0 _ _ _ = []
solve n from help to = (solve (n-1) from to help) ++ [(from,to)] ++ (solve (n-1) help from to)

However my iterative version looks terrible with a lot of code repetition:

hanoi n = map rep $ solve [1..n] [] [] where
 rep (x,y) | odd n = ([1,3,2] !! (x-1), [1,3,2] !! (y-1))
 | otherwise = (x,y) 
solve from help to = head $ mapMaybe ready $ iterate step (from,help,to,[]) where
 step (1:xs,ys,zs,sol) = let (xs',zs',sol') = try xs zs 1 3 ((1,2):sol)
 in (xs',1:ys,zs',sol')
 step (xs,1:ys,zs,sol) = let (xs',ys',sol') = try xs ys 1 2 ((2,3):sol)
 in (xs',ys',1:zs,sol')
 step (xs,ys,1:zs,sol) = let (ys',zs',sol') = try ys zs 2 3 ((3,1):sol)
 in (1:xs,ys',zs',sol')
 try [] [] _ _ sol = ([],[], sol) 
 try (x:xs) [] a b sol = (xs,[x], (a,b):sol) 
 try [] (y:ys) a b sol = ([y],ys, (b,a):sol) 
 try (x:xs) (y:ys) a b sol | x < y = (xs,x:y:ys, (a,b):sol)
 | y < x = (y:x:xs,ys, (b,a):sol) 
 ready ([],[],_,sol) = Just $ reverse sol
 ready ([],_,[],sol) = Just $ reverse sol
 ready _ = Nothing

Any ideas? More general, how to deal with situations like this where you have a lot of different cases and args?

[Clarification]

With "iterative solution" I mean the algorithm described here: http://en.wikipedia.org/wiki/Tower_of_Hanoi#Iterative_solution

AJNeufeld
35.2k5 gold badges41 silver badges103 bronze badges
asked Apr 6, 2011 at 18:48
\$\endgroup\$
1

1 Answer 1

4
\$\begingroup\$

Umm. What about

import Data.Bits
hanoi :: Int -> [(Int, Int)]
hanoi n = map (\x -> ((x .&. (x-1)) `mod` 3, ((x .|. (x-1)) + 1) `mod` 3)) [1..shift 1 n]
main = print $ hanoi 5

?

answered Apr 15, 2011 at 19:03
\$\endgroup\$
1
  • \$\begingroup\$ It almost works, but calling "hanoi 3" gives you an extra move at the end: [(0,2),(0,1),(2,1),(0,2),(1,0),(1,2),(0,2),(0,1)]. Same with "hanoi 4". Still, this is pretty ingenious, and easily fixed by adding "init $" in front of your map. \$\endgroup\$ Commented Jul 6, 2011 at 15:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.