Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Philip + Christoph #5

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ erl_crash.dump
# Ignore package tarball (built via "mix hex.build").
run_length_encoding-*.tar

.tool-versions
54 changes: 54 additions & 0 deletions lib/run_length_encoding.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,63 @@ defmodule RunLengthEncoding do
"""
require Logger


# accu :: [ { char, count:int } ]
# [ { "A", 2 }, { "B", 1 } ]
defp encode_rec([], accu), do: accu
defp encode_rec([h | t], [{h, count} | accu]), do: encode_rec(t, [{h, count + 1} | accu])
defp encode_rec([h | t], [{old, count} | accu]), do: encode_rec(t, [{h, 1} | [{old, count} | accu]])
defp encode_rec([h | t], []), do: encode_rec(t, [{h, 1}])

defp rle_char({char, 1}, result), do: char <> result
defp rle_char({char, count}, result), do: "#{count}" <> char <> result

defp encode_assemble(tuples) do
tuples
|> Enum.reduce("", &rle_char/2)
end

def encode(string) do
encode_rec(String.codepoints(string), [])
|> encode_assemble
end








@digits 0..9
|> Enum.map(&to_string/1)

# accu :: { reverse_digits:[char], [ { reverse_digits:[char], char } ] }
# { [], [ { ["1","2"], "A" } ] }
defp decode_rec([], accu), do: accu
defp decode_rec([h | t], {number, accu}) when not (h in @digits), do: decode_rec(t, {[], [{number, h} | accu]})
defp decode_rec([h | t], {number, accu}), do: decode_rec(t, {[h | number], accu})

defp digits_to_int([]), do: 1
defp digits_to_int(digits),
do: digits
|> Enum.join("")
|> String.to_integer

defp rldecode_char({reverse_digits, char}, result) do
count = reverse_digits
|> Enum.reverse
|> digits_to_int
String.duplicate(char, count) <> result
end

defp decode_assemble({_, chars}) do
chars
|> Enum.reduce("", &rldecode_char/2)
end

def decode(string) do
decode_rec(String.codepoints(string), {[], []})
|> decode_assemble
end
end
12 changes: 0 additions & 12 deletions test/run_length_encoding_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,64 +6,52 @@ defmodule RunLengthEncodingTest do
assert RunLengthEncoding.encode("") === ""
end

@tag :pending
test "encode single characters only are encoded without count" do
assert RunLengthEncoding.encode("XYZ") === "XYZ"
end

@tag :pending
test "encode string with no single characters" do
assert RunLengthEncoding.encode("AABBBCCCC") == "2A3B4C"
end

@tag :pending
test "encode single characters mixed with repeated characters" do
assert RunLengthEncoding.encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB") ===
"12WB12W3B24WB"
end

@tag :pending
test "encode multiple whitespace mixed in string" do
assert RunLengthEncoding.encode(" hsqq qww ") === "2 hs2q q2w2 "
end

@tag :pending
test "encode lowercase characters" do
assert RunLengthEncoding.encode("aabbbcccc") === "2a3b4c"
end

@tag :pending
test "decode empty string" do
assert RunLengthEncoding.decode("") === ""
end

@tag :pending
test "decode single characters only" do
assert RunLengthEncoding.decode("XYZ") === "XYZ"
end

@tag :pending
test "decode string with no single characters" do
assert RunLengthEncoding.decode("2A3B4C") == "AABBBCCCC"
end

@tag :pending
test "decode single characters with repeated characters" do
assert RunLengthEncoding.decode("12WB12W3B24WB") ===
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB"
end

@tag :pending
test "decode multiple whitespace mixed in string" do
assert RunLengthEncoding.decode("2 hs2q q2w2 ") === " hsqq qww "
end

@tag :pending
test "decode lower case string" do
assert RunLengthEncoding.decode("2a3b4c") === "aabbbcccc"
end

@tag :pending
test "encode followed by decode gives original string" do
original = "zzz ZZ zZ"
encoded = RunLengthEncoding.encode(original)
Expand Down