34問目
http://projecteuler.net/index.php?section=problems&id=34
各桁の数字の階乗の和が元の数と等しくなるような数を全て足し合わせる。
9の階乗は6桁なので、求める数は高々7桁だと分かります。(それ以上だと元の数の桁数が階乗の和の桁数より必ず大きくなる)
あとは全ての数を調べているのですが、よく考えたら階乗の和になる数は限られているので、それに絞って調べた方がいいですね。
ちょっと考えてみよう。
import Data.Char main = print euler034 euler034 :: Integer euler034 = sum $ filter factSum [10..(facts !! 9)*7] where factSum n = n == (sum $ map ((facts !!) . digitToInt) $ show n) facts :: [Integer] facts = 1 : scanl1 (*) [1..]
という訳で修正したのが↓。
断然速いです。
import Data.Char import Data.List main = print $ sum $ euler034 euler034 :: [Int] euler034 = map (sum . map (facts !!)) $ filter factSum $ concat [ perm n | n <- [2..7] ] where factSum xs = xs == (map digitToInt $ sort $ show $ sum $ map (facts !!) xs) perm :: Int -> [[Int]] perm 1 = [ [x] | x <- [0..9] ] perm n = [ x:xs | xs <- perm (n-1), x <- takeWhile (<= head xs) [0..9] ] facts :: [Int] facts = 1 : scanl1 (*) [1..]