Hello Communiity,
I would like know which is the best form for count one string with the following format
input = “abcaaabbb”
output =“abca3b3”
Regards
Hello Communiity,
I would like know which is the best form for count one string with the following format
input = “abcaaabbb”
output =“abca3b3”
Regards
Here’s my try:
input
|> String.graphemes()
|> Enum.chunk_by(& &1)
|> Enum.map_join(fn
[char] -> char
[char | _] = chars -> [char, length(chars) |> to_string()]
end)
A recursive try…
defmodule Demo do
def compress(str) when is_binary(str) do
do_compress(str, {<<>>, nil, 0})
end
defp do_compress(<<>>, {acc, _previous, 0}), do: acc
defp do_compress(<<>>, {acc, previous, count}),
do: acc <> <<previous::utf8>> <> to_string(count + 1)
defp do_compress(<<c::utf8, rest::binary>>, {acc, previous, count})
when c == previous,
do: do_compress(rest, {acc, previous, count + 1})
defp do_compress(<<c::utf8, rest::binary>>, {acc, _previous, 0}),
do: do_compress(rest, {acc <> <<c::utf8>>, c, 0})
defp do_compress(<<c::utf8, rest::binary>>, {acc, _previous, count}),
do: do_compress(rest, {acc <> to_string(count + 1), c, 0})
end
then…
iex(1)> Demo.compress "abcaaabbb"
"abca3b3"
Great Solutions, Thanks qhwa, mudasobwa, kokolegorille
wouldn’t let you get away without a solution featuring TCR and improper lists!
defmodule Demo do
def compress(str) when is_binary(str) do
str
|> do_compress({[], 1})
|> IO.iodata_to_binary()
end
#terminal condition
def do_compress("", {acc, _}), do: acc
def do_compress(str = <<char::utf8, char::utf8, _::binary>>, {acc, count}) do
# drop the first character and increment the count
<<_::utf8>> <> rest = str
do_compress(rest, {acc, count + 1})
end
def do_compress(<<char::utf8>> <> rest, {acc, 1}) do
# no match, singleton, don't tag; reset count.
do_compress(rest, {[acc | <<char::utf8>>], 1})
end
def do_compress(<<char::utf8>> <> rest, {acc, n}) do
# no match, multiples, add the tag, reset count.
do_compress(rest, {[acc, <<char::utf8>> | to_string(n)], 1})
end
end