Problem 168

http://projecteuler.net/index.php?section=problems&id=168

先頭の数字と約数を決めると次々と後の数字が分かっていく。

これもまた、循環を利用。

import Data.List
expand d hd = (div hd d:).unfoldr f.snd.g $ hd
where f x | x == hd = Nothing
| otherwise = Just $ g x
g x = let (q,r) = divMod x d in (q,q+10*r)
p168 = foldl (a b -> (a+b) `mod` (10^5))  $ 55005 : [count $ expand d hd | d <-[2..9], hd <- [1..9]]
where count xs | head xs ==  = 
| otherwise = appear xs * last5 xs `mod` (10^5)
appear = div 100.genericLength
last5 = listToInteger.reverse.take 5.reverse
listToInteger = foldl (a b->10*a+b) .map toInteger

ちなみに55005は111,99999などの約数1からの寄与。

More Reading
Newer// Problem 167