primes = (2 : filter (check primes) [3..]) where check (p:ps) n | p*p > n = True | n `mod` p == 0 = False | otherwise = check ps n 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