Project Eulerを解き始めた

Haskellの復習を始めてしまったので、その流れでProject Eulerの問題を解く。

Problem 1

リスト内包表記で一発。

answer1 = sum [x | x <- [1..999], (x `mod` 3 == 0) || (x `mod` 5 == 0)]

Problem 2

フィボナッチ数列の問題。解答時のコードは汚くて恥ずかしい。
最初、filter関数で400万以下の数を集めようとしたが、無限リストに適用しても意味が無いことに気づきtakeWhile関数を使う。

-- 解答時のコード

answer2 = 2 + sum [x | x <- takeWhile (<= 4000000) (mkFibs 1 2), even x]

mkFibs :: Integer -> Integer -> [Integer]
mkFibs n1 n2 = [n1 + n2] ++ mkFib n2 (n1 + n2)


フィボナッチ数列のきれいな書き方を教わったのでちょっと改善。

answer2 = sum [x | x <- takeWhile (<= 4000000) fibs, even x]
fibs = 1:2:zipWith (+) fibs (tail fibs)

Problem 3

基本的に素因数分解するだけ。素因数分解の部分をもうちょっと綺麗にかけないかなあ。

answer3 = maximum $ factorize 600851475143

factorize :: Integer -> [Integer]
factorize 1 = [1]
factorize n = factorize' n (2:[3,5..])

factorize' n (x:xs)
	| n < x * x		= [n]
	| n `mod` x == 0	= x : factorize' (n `div` x) (x:xs)
	| otherwise		= factorize' n xs