perfect-numbers
This commit is contained in:
41
elixir/perfect-numbers/lib/perfect_numbers.ex
Normal file
41
elixir/perfect-numbers/lib/perfect_numbers.ex
Normal file
@@ -0,0 +1,41 @@
|
||||
defmodule PerfectNumbers do
|
||||
@doc """
|
||||
Determine the aliquot sum of the given `number`, by summing all the factors
|
||||
of `number`, aside from `number` itself.
|
||||
|
||||
Based on this sum, classify the number as:
|
||||
|
||||
:perfect if the aliquot sum is equal to `number`
|
||||
:abundant if the aliquot sum is greater than `number`
|
||||
:deficient if the aliquot sum is less than `number`
|
||||
"""
|
||||
@spec classify(number :: integer) :: {:ok, atom} | {:error, String.t()}
|
||||
def classify(number) when number <= 0, do: {:error, "Classification is only possible for natural numbers."}
|
||||
def classify(1), do: {:ok, :deficient}
|
||||
def classify(number) do
|
||||
sum =
|
||||
number
|
||||
|> divisors()
|
||||
|> Enum.sum()
|
||||
|
||||
cond do
|
||||
sum == number ->
|
||||
{:ok, :perfect}
|
||||
|
||||
sum > number ->
|
||||
{:ok, :abundant}
|
||||
|
||||
sum < number ->
|
||||
{:ok, :deficient}
|
||||
end
|
||||
end
|
||||
|
||||
defp divisors(number) do
|
||||
for i <- 1..round(number ** 0.5), reduce: [] do
|
||||
acc -> if rem(number, i) == 0, do: [i, div(number, i) | acc], else: acc
|
||||
end
|
||||
|> Enum.uniq()
|
||||
|> Enum.sort()
|
||||
|> Enum.drop(-1)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user