Reputation: 701
I'm studying functional programming with Elixir and came across the following exercise:
"You are given a two-digit integer n. Return the sum of its digits."
The solution I came up looks a bit "hairy".
I wonder if someone could give some advice into Elixir std lib functions/module and provide a better solution.
I know I could just go with n%10 + Math.floor(n/10)
(js) but Id' like to know if a solution using Elixir functions would be more or less what I came up with:
def addTwoDigits(n) do
n |> Integer.to_string
|> String.split("") # Number 44 would give a list ["",4,4,""]
|> Enum.filter(&(&1 != ""))
|> Enum.map(&(String.to_integer(&1)))
|> Enum.reduce(&(&1+&2))
end
Upvotes: 1
Views: 2080
Reputation: 10138
You should avoid unnecessary operations (conversion to string, conversion to list, etc.).
I'd go with the following, using div/2
& rem/2
in a recursive function:
def addTwoDigits(n) do
if n > 0, do: rem(n, 10) + addTwoDigits(div(n, 10)), else: n
end
I used this to compare our functions:
By working with integers you avoid useless conversions/iterations & get a function that computes your result ~4 times faster!
Upvotes: 1
Reputation: 1970
Easiest and closest to your initial thought, would be by leveraging the following function:
Integer.digits(123)
[1, 2, 3]
to obtain each individual digit as documented here
You can then simply do:
def sum_digits_in_number(n) do
n
|> Integer.digits
|> Enum.sum
end
Upvotes: 2
Reputation: 121010
Since it’s an exercise / learning example, I would assume the answer expected would be a function with many clauses:
defmodule M do
def add(num, acc \\ 0)
def add(num, _acc) when num > 99, do: raise("Invalid #{num}")
def add(num, acc) when num < 10, do: acc + num
def add(num, acc), do: add(rem(num, 10), acc + div(num, 10))
end
IO.puts M.add(35)
#⇒ 8
IO.puts M.add(5)
#⇒ 5
IO.puts M.add(88)
#⇒ 16
IO.puts M.add(101)
#⇒ ** (RuntimeError) Invalid 101
This is definitely a huge overkill for this particular task, but think how easy is to make this code to sum integers having 3 numbers (unlike any other non-functional approach.)
Upvotes: 1