List traversal vs. recursive binary pattern-matching

I believe that second one:

However your description is not enough clear for me …

  • Is stripping spaces the first thing you do?
  • How do you then fetch index?
  • Do you use something like String.split/2?

In my opinion not only index should be incremented on recursive pattern-matching, but also the calculation could be done in exactly same step.

This is what I have written in few minutes …
defmodule Example do
  def sample(string), do: string |> parse(0, [[]]) |> Enum.sum() |> Kernel.rem(10)

  defp parse("", _index, [[] | acc]), do: acc

  defp parse("", index, [last | tail]), do: [get_value(last, index) | tail]

  defp parse(<<" ", rest::binary>>, 0, [[]]), do: parse(rest, 0, [[]])

  defp parse(<<" ", rest::binary>>, index, [last | tail]) do
    parse(rest, index + 1, [[], get_value(last, index) | tail])
  end

  defp parse(<<digit::utf8, rest::binary>>, index, [last | tail]) when digit in ?0..?9 do
    parse(rest, index, [[digit | last] | tail])
  end

  defp get_value(list, index), do: list |> Enum.reverse() |> List.to_integer() |> calculate(index)

  defp calculate(integer, index), do: integer * index
end
Feel free to compare it with your current code.

In this code we have such 3 steps:

  1. Parsing - just simple recursive iteration
    At end of string and/or at any whitespace (except whitespaces at start) we need to reverse list (because of previously used [head | tail] optimization), convert it to integer and do some calculation based on the incremented (by any whitespaces except those at start) index.
  2. After that we are calling Enum.sum/1
  3. And finally calculatiing remainder of division by 10
1 Like