Created
January 30, 2014 07:53
-
-
Save nnabeyang/8704288 to your computer and use it in GitHub Desktop.
左端のn段のハノイの塔を最小回数で右端に移動させるときの最初の一手について ref: http://qiita.com/nnabeyang/items/5339a3248284b0039255
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Monad.Writer | |
size :: [[a]] -> Int | |
size = foldr (\ xs n -> length xs + n) 0 | |
move :: [[Int]] -> (Int, Int) -> Writer [String] [[Int]] | |
move xss (from, to) = return([move_ xs y (from, to) i| (xs, i) <- zip xss [0..]]) | |
where (y:_) = xss !! from | |
move_ :: [Int] -> Int -> (Int, Int) -> Int -> [Int] | |
move_ [] y (from, to) i = if i == to then [y] else [] | |
move_ (x:xs) y (from, to) i |i == from = xs | |
|i == to = (y:x:xs) | |
|otherwise = (x:xs) | |
hanoi :: Int -> Writer [String] [[Int]] | |
hanoi n = hanoi_ n [[0..(n-1)], [], []] (0, 1, 2) | |
hanoi_ :: Int -> [[Int]] -> (Int, Int, Int) -> Writer [String] [[Int]] | |
hanoi_ 0 xss (from, work, to) = return(xss) | |
hanoi_ n xss (from, work, to) = do xss' <- hanoi_ (n-1) xss (from, to, work) | |
xss'' <- move xss' (from, to) | |
tell [show(xss'') ++" (" ++ show(from) ++ " -> " ++ show(to) ++ ")"] | |
xss''' <- hanoi_ (n-1) xss'' (work, from, to) | |
return(xss''') | |
show_hanoi :: Int -> IO () | |
show_hanoi n = mapM_ putStrLn $ snd $ runWriter (hanoi n) | |
test :: Int -> IO () | |
test n = mapM_ putStrLn $ take n $ map (head . snd . runWriter . hanoi) [1..] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment