Эликсир: сумма 2+ цифр - PullRequest
0 голосов
/ 15 мая 2018

Я изучаю функциональное программирование с помощью Elixir и наткнулся на следующее упражнение:

"Вам дано двузначное целое число n. Верните сумму его цифр."

Решение, которое я нашел, выглядит немного "волосатым". Интересно, кто-нибудь мог бы дать какой-нибудь совет в Elixir std lib functions / module и предоставить лучшее решение. Я знаю, что мог бы просто пойти с n%10 + Math.floor(n/10) (js), но я хотел бы знать, будет ли решение, использующее функции Elixir, более или менее то, что я придумал:

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

Ответы [ 3 ]

0 голосов
/ 15 мая 2018

Поскольку это пример упражнения / обучения, я предполагаю, что ожидаемый ответ будет функцией со многими предложениями:

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

Это определенно огромный перебор для этой конкретной задачи, но подумайте, насколько просто сделать этот код для суммирования целых чисел, имеющих 3 числа (в отличие от любого другого нефункционального подхода).

0 голосов
/ 15 мая 2018

Проще всего и ближе к вашей первоначальной мысли, используя следующую функцию:

Integer.digits(123)
[1, 2, 3]

для получения каждой отдельной цифры, как задокументировано здесь

Вы можете просто сделать:

def sum_digits_in_number(n) do
   n
   |> Integer.digits
   |> Enum.sum
end
0 голосов
/ 15 мая 2018

Вам следует избегать ненужных операций (преобразование в строку, преобразование в список и т. Д.).

Я бы пошел со следующим, используя div/2 & rem/2 в рекурсивной функции:

def addTwoDigits(n) do
  if n > 0, do: rem(n, 10) + addTwoDigits(div(n, 10)), else: n
end

Я использовал это для сравнения наших функций:

  • Ваша функция выполняется за ~ 16 мкс
  • функция выше работает в течение ~ 4 мкс

Работая с целыми числами, вы избегаете бесполезных преобразований / итераций и получаете функцию, которая вычисляет ваш результат ~ в 4 раза быстрее!

...