d(n)をnの真の約数(nの約数でnより小さいもの)の和と定義する。
a≠bでd(a)=bかつd(b)=aのとき、aとbは友愛数と呼ばれる。
例えば220の真の約数は1,2,4,5,10,11,20,22,44,55,110なので、d(220)=284と なる。284の真の約数は1,2,4,71,142なので、d(284)=220となる。
10000未満の全ての友愛数の和を求めよ。
友愛数とは2つの異なる自然数a,bで自分自身を含まない約数の和が他方と等し くなるものである。まずは問題12で定義したfactorsを元に自分自身を含まない 約数のリストを求めるproperFactorsを定義する。1で割り切れるか試す部分を 特別扱いし2以降についてはfactorsと同様に処理することで自分自身を含まな い約数のリストを求めることができる。
次に友愛数かどうかのチェックをする関数amicableを定義する。ここでは友愛 数の定義をそのまま実装し、引数aの約数の和bを求め、aとbが異なり、bの約数 の和がaであった場合に友愛数であると判定する。最後に10000未満の数のリス トからfilterで友愛数を取り出しsumで和を求める。
properFactors n = 1 : p' n 2 []
where p' n x l
| x * x > n = l
| x * x == n = x : l
| n `mod` x == 0 = x : p' n (x + 1) ((n `div` x) : l)
| otherwise = p' n (x + 1) l
amicable a = b /= a && (sum $ properFactors b) == a
where b = sum $ properFactors a
euler021 = sum $ filter amicable [1..9999]
