primes = 2 : [n | n <- [3..], isPrime n] where isPrime n = foldr (\p r-> p*p>n || (rem n p /= 0 && r)) True primes sumDiv n = (divs n primes) - n where divs 1 _ = 1 divs n (p:ps) = if p*p > n then n+1 else let (c, r) = cnt n p 0 in if c == 0 then divs n ps else (sum $ take (c+1) $ iterate (*p) 1) * (divs r ps) cnt n p c | mod n p == 0 = cnt (div n p) p (c+1) | otherwise = (c, n) friends :: [(Integer, Integer)] friends = filter (\(x, s) -> x < s && sumDiv s == x) $ map (\x -> (x, sumDiv x)) [1..] main = mapM print $ take 37 friends