Skip to content

Instantly share code, notes, and snippets.

@darkhelmet
Created January 19, 2012 06:11
Show Gist options
  • Save darkhelmet/1638297 to your computer and use it in GitHub Desktop.
Save darkhelmet/1638297 to your computer and use it in GitHub Desktop.
Number classification in Haskell
data Classification = Perfect | Abundant | Deficient deriving (Eq, Show, Ord)
squareRoot :: Int -> Int
squareRoot = floor . sqrt . fromIntegral
isFactor :: Int -> Int -> Bool
isFactor a b = a `mod` b == 0
factors :: Int -> [Int]
factors n = lowFactors ++ highFactors
where lowFactors = filter (isFactor n) [1..limit]
limit = squareRoot n
highFactors = map (n `div`) lowFactors
classify :: Int -> (Int, Classification)
classify n
| sumOfFactors == n' = (n, Perfect)
| sumOfFactors < n' = (n, Deficient)
| sumOfFactors > n' = (n, Abundant)
where n' = 2 * n
sumOfFactors = sum $ factors n
perfectNumbers = filter (\(n, c) -> c == Perfect) $ map classify [1..]
@kcharter
Copy link

Nice! Are you planning to use classify for something else where you need the result type to be (Int, Classification)? If not, you could simplify the return type of classify and slightly simplify perfectNumbers.

@darkhelmet
Copy link
Author

It was originally just returning the classification, but I wanted the number too....didn't think too hard about it. It's not for anything, I was just watching a talk where he was discussing this algorithm.

@kcharter
Copy link

Do you have a link to the talk? I'd be interested.

@darkhelmet
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment