14問目
http://projecteuler.net/index.php?section=problems&id=14
以下の式で定義される数列(コラッツ予想によれば必ず1で終わる)があったとき、数列の長さを最大にする百万未満のnを求める。
n → n/2 (nが偶数のとき)
n → 3n + 1 (nが奇数のとき)
数列の長さをリストに格納して、maximumとtakeWhileで最大となるnを求めています。
本当はmaximumByを使って簡単に書きたかった(コメントアウト部分)のですが、10倍くらい時間がかかってしまうので止めました。どうやら関数lenが何度も評価されてるみたいです。なぜだろう?
main = print $ euler014 999999 euler014 :: Integer -> Int euler014 n = (+ 1) $ length $ takeWhile (< (maximum lens)) lens where lens = map len [1..n] -- euler014 :: Integer -> Integer -- euler014 n = maximumBy (comparing len) [1..n] len :: Integer -> Integer len 1 = 1 len n = len (seq' n) + 1 seq' :: Integer -> Integer seq' n | (mod n 2 == 0) = div n 2 | otherwise = 3 * n + 1