-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathMain.hs
38 lines (29 loc) · 1.01 KB
/
Main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{-# LANGUAGE ImportQualifiedPost #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
module Main where
import Control.Arrow
import Data.List qualified as L
import System.Environment
import Prime
main :: IO ()
main = do
ln : _ <- (read <$>) <$> getArgs
putStr . unlines
$ (\(n, m) -> show n ++ "\t" ++ show m) <$> take ln amicables
pairs :: Int -> [(Int, (Int, Int))]
pairs n = (id &&& (n `divMod`)) <$> takeWhile ((n >=) . (^ (2 :: Int))) primes
popPrime :: Int -> Maybe (Int, Int)
popPrime 1 = Nothing
popPrime n = case filter ((== 0) . snd . snd) $ pairs n of
[] -> Just (n, 1)
(p, (n', _)) : _ -> Just (p, n')
primeFactorization :: Int -> [Int]
primeFactorization = L.unfoldr popPrime
divisors :: Int -> [Int]
divisors = L.nub . L.sort . init
. (product <$>) . L.subsequences . primeFactorization
testAmicables :: Int -> Bool
testAmicables n = let m = sum (divisors n) in n == sum (divisors m)
amicables :: [(Int, Int)]
amicables = filter ((<) <$> fst <*> snd)
[ (n, sum $ divisors n) | n <- [2 ..], testAmicables n ]