Life Goes On

まあまあだけど楽しんでる方です

21問目

http://projecteuler.net/index.php?section=problems&id=21
一万未満の友愛数の合計を求める。
友愛数というのはそれぞれの約数の和が相手と等しい数同士のことだそうですが、約数の和が自分自身と等しい数は除いています。
今回は平方数の約数もきちんと求めました。しかし約数の求め方一つでも色々な書き方があるものですね。
http://d.hatena.ne.jp/takatoh/20080328/euler012
http://www.euphe.net/memo/euler02.html

import Data.List

main = print $ sum $ euler021 10000
 
euler021 :: Int -> [Int]
euler021 limit = filter isAmicable [1..limit]
 
isAmicable :: Int -> Bool
isAmicable n = (n == (sumDivisors $ sumDivisors n) && n /= sumDivisors n)
 
sumDivisors :: Int -> Int
sumDivisors n = sum $ nub $ [1] ++ halfDivisors ++ (map (div n) halfDivisors)
  where halfDivisors = filter ((== 0) . mod n) [2..root]
        root = floor $ sqrt $ fromIntegral n