Last active
June 7, 2016 01:23
-
-
Save stockwellb/8ec6883346eb48517fa710bd5fac427b to your computer and use it in GitHub Desktop.
Run Length Encoding in Elixir.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule RunLength do | |
def encode(data) do | |
String.graphemes(data) |> do_encode | |
end | |
defp do_encode([]) do | |
"" | |
end | |
defp do_encode([h|t]) do | |
do_encode(1, h, t) | |
end | |
defp do_encode(1, c, []) do | |
"#{c}" | |
end | |
defp do_encode(n, c, []) do | |
"#{n}#{c}" | |
end | |
defp do_encode(n, c, [c|t]) do | |
do_encode(n + 1, c, t) | |
end | |
defp do_encode(n, c, [h|t]) do | |
do_encode(n, c, []) <> do_encode(1, h, t) | |
end | |
def decode(data) do | |
String.graphemes(data) |> do_decode | |
end | |
defp do_decode([]) do | |
"" | |
end | |
defp do_decode([h|[]]) do | |
h | |
end | |
defp do_decode([first|t]) do | |
[second|_] = t | |
case Integer.parse(first) do | |
:error -> first <> do_decode t | |
{i, _} -> cond do | |
i > 2 -> second <> do_decode [Integer.to_string(i-1)|t] | |
i == 2 -> second <> do_decode t | |
end | |
end | |
end | |
end | |
ExUnit.start | |
defmodule RunLengthTest do | |
use ExUnit.Case, async: true | |
test "encode" do | |
x = RunLength.encode("ELIIIIXIIIIR") | |
assert x == "EL4IX4IR" | |
end | |
test "encode empty returns empty" do | |
x = RunLength.encode("") | |
assert x == "" | |
end | |
test "decode" do | |
x = RunLength.decode("EL4IX4IR") | |
assert x == "ELIIIIXIIIIR" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment