Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

group or count duplicated letters in elixir

Tags:

elixir

I'm trying to count duplicated letters on a String in Elixir. I did try some attempts, but no success until now.

Let's take this string as example: "AAABBAAC"

The desired output would be "3A2B2A1C".

Converting this string to a List, I was able to count every letter, resulting in "5A2B1C", but I have to count following the order.

This is the code I was doing:

string
|> String.graphemes
|> Enum.reduce([], fn(letter, acc) -> Keyword.update(acc, letter, 1, &(&1 + 1)) end)

But, in my tests, I'm trying to produce a List, like this ["AAA", "BB", "AA", "C"], so I can easely count with String.lenght.

Looks like using Enum.chunk_by I'm getting closer to a solution.

Is there a way to produce this?

like image 776
Alexandre S Hostert Avatar asked Nov 17 '25 11:11

Alexandre S Hostert


1 Answers

If you implement this using a recursive approach, you can easily keep track of the last occurred character and its current count, as well an accumulator that holds the result so far. If the current character equals the last character you just increase the count. If the two differ, you add the last character and its count to the accumulator and proceed with the next character until the string is empty. Finally, you encode the final value and return the result.

defmodule RunLengthEncoding do
  # public interface, take first char and remember it as the current value
  def encode(<<char::utf8, rest::binary>>) do
    do_encode(rest, char, 1, "")
  end

  # current == last, increase the count and proceed
  defp do_encode(<<char::utf8, rest::binary>>, char, count, acc) do
    do_encode(rest, char, count + 1, acc)
  end

  # current != last, reset count, encode previous values and proceed
  defp do_encode(<<char::utf8, rest::binary>>, last, count, acc) do
    do_encode(rest, char, 1, acc <> to_string(count) <> <<last::utf8>>)
  end

  # input empty, encode final values and return
  defp do_encode("", last, count, acc) do
    acc <> to_string(count) <> <<last::utf8>>
  end
end
like image 159
Patrick Oscity Avatar answered Nov 20 '25 02:11

Patrick Oscity



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!