Project Euler 55,56

Problem 55

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


特になにもない。

digits 0 = []
digits n = (digits (div n 10)) ++ [mod n 10]
numerize a = foldl1 (\x y -> x * 10 + y) a
rev = numerize . reverse . digits

is_palindromic n = n == (rev n)
step n = n + (rev n)

is_Lychrel n = f n 50 where
        f n 0 = True
        f n m = if is_palindromic p then False else f p (m - 1)
                                                where p = step n

main = print (length (filter is_Lychrel [1..9999]))

Problem 56

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


ざっと書くと、

sum_digits 0 = 0
sum_digits n = (sum_digits (div n 10)) + (mod n 10)

ary :: [Integer]
ary = [1..100]
a = [ sum_digits (a^b) | a <- ary, b <- ary ]
main = print (foldr max 0 a)

べき乗ではなく、1回ずつ掛け算すると次のようになる。ただしあまり速くならなかった。

sum_digits 0 = 0
sum_digits n = (sum_digits (div n 10)) + (mod n 10)

pow n 0 = [1]
pow n m = (n * (head a)):a where a = pow n (m - 1)
max_pow n m = foldr max 0 (map sum_digits (pow n m))

main = print (foldr max 0 (map (\n -> max_pow n 100) [1..100]))