今日は Problem 14。
cf. Project Euler – Problem 14
コラッツ問題の数列を求めるのは以前にやったのを流用。あとは力任せに…
module Main (main) where collatz :: Int -> [Int] collatz 1 = 1 : [] collatz n | n `mod` 2 == 0 = n : collatz (n `div` 2) | otherwise = n : collatz (n * 3 + 1) euler014 :: Int -> [Int] euler014 n = snd $ foldl g (0, []) $ map f [1..n] where f x = ((length.collatz) x, x) g (x,zs) (l,z) | x < l = (l, z:[]) | x == l = (x, z:zs) | otherwise = (x, zs) main :: IO () main = mapM_ (putStrLn.show) $ euler014 1000000
やったらあえなくスタックオーバーフローに。ありゃ。
^o^ >runhaskell euler014.hs *** Exception: stack overflow
100,000までだったらうまくいったので間違ってはいないと思う。たぶん数列がすごく長くなる数があるんだろうな。再挑戦はまた今度。
あと,ついでに書いておくと,各数の数列にはおなじ部分列が何度も出現する。これを覚えておけば計算量を少なくできるんだけど,メモ化のやり方がわからない。