Problem55 - ProjectEuler
30分プログラム、その332。Problem55 - Project Euler。
47とその反転を足し合わせると, 47 + 74 = 121となり, 回文数になる.
全ての数が素早く回文数になるわけではない. 349を考えよう,
- 349 + 943 = 1292,
- 1292 + 2921 = 4213
- 4213 + 3124 = 7337
349は, 3回の操作を経て回文数になる.
まだ証明はされていないが, 196のようないくつかの数字は回文数にならないと考えられている. 反転したものを足すという操作を経ても回文数にならないものをLychrel数と呼ぶ. 先のような数の理論的な性質により, またこの問題の目的のために, Lychrel数で無いと証明されていない数はLychrel数だと仮定する.
更に, 10000未満の数については以下を仮定してよい.実際, 10677が50回以上の操作を必要とする最初の数である: 4668731596684224866951378664 (53回の操作で28桁のこの回文数になる).
驚くべきことに, 回文数かつLychrel数であるものが存在する. 最初の数は4994である.
10000未満のLychrel数の個数を答えよ.
Erlangでやろうとしたら、処理系が入ってなかったのでHaskellで。驚くべきことに, 回文数かつLychrel数であるものが存在する
あたりがつまりどころかもしれない。
使い方
*Main> solve 249
ソースコード
import Data.List splitDigitRev :: Integer -> [Integer] splitDigitRev 0 = [] splitDigitRev n = n `mod` 10:splitDigitRev (n `div` 10) makeDigit :: [Integer] -> Integer makeDigit xs = foldl1 (\x y->10*x+y) xs isCycle :: Integer -> Bool isCycle xs = xs == (makeDigit $ splitDigitRev xs) next n = n + (makeDigit.splitDigitRev) n isLychrel x = let r = find isCycle $ take 50 $ iterate next (next x) in r == Nothing solve = length $ filter isLychrel [1..10000]