Skip to content

Commit a6fedb2

Browse files
authored
run-length-encoding (#50)
1 parent 2d0d876 commit a6fedb2

File tree

9 files changed

+213
-0
lines changed

9 files changed

+213
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,14 @@
382382
"practices": [],
383383
"prerequisites": [],
384384
"difficulty": 4
385+
},
386+
{
387+
"slug": "run-length-encoding",
388+
"name": "Run-Length Encoding",
389+
"uuid": "909d5671-60a1-498f-80ce-82d6e0b88465",
390+
"practices": [],
391+
"prerequisites": [],
392+
"difficulty": 4
385393
}
386394
]
387395
},
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
return {
2+
default = {
3+
ROOT = { '.' }
4+
}
5+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Instructions
2+
3+
Implement run-length encoding and decoding.
4+
5+
Run-length encoding (RLE) is a simple form of data compression, where runs (consecutive data elements) are replaced by just one data value and count.
6+
7+
For example we can represent the original 53 characters with only 13.
8+
9+
```text
10+
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB"
11+
```
12+
13+
RLE allows the original data to be perfectly reconstructed from the compressed data, which makes it a lossless data compression.
14+
15+
```text
16+
"AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE"
17+
```
18+
19+
For simplicity, you can assume that the unencoded string will only contain the letters A through Z (either lower or upper case) and whitespace.
20+
This way data to be encoded will never contain any numbers and numbers inside data to be decoded always represent the count for the following character.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"glennj"
4+
],
5+
"files": {
6+
"solution": [
7+
"run_length_encoding.moon"
8+
],
9+
"test": [
10+
"run_length_encoding_spec.moon"
11+
],
12+
"example": [
13+
".meta/example.moon"
14+
]
15+
},
16+
"blurb": "Implement run-length encoding and decoding.",
17+
"source": "Wikipedia",
18+
"source_url": "https://en.wikipedia.org/wiki/Run-length_encoding"
19+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
encode: (plaintext) ->
3+
encoded, prev, n = '', '', 0
4+
5+
add_run = -> encoded ..= "#{if n <= 1 then '' else n}#{prev}"
6+
7+
for char in plaintext\gmatch '.'
8+
if char != prev
9+
add_run!
10+
n = 1
11+
prev = char
12+
else
13+
n += 1
14+
add_run!
15+
encoded
16+
17+
18+
decode: (ciphertext) ->
19+
decoded, length = '', ''
20+
for char in ciphertext\gmatch '.'
21+
if char\find '%d'
22+
length ..= char
23+
else
24+
n = tonumber(length) or 1
25+
decoded ..= string.rep char, n
26+
length = ''
27+
decoded
28+
}
29+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
module_imports: {'encode', 'decode'},
3+
4+
generate_test: (case, level) ->
5+
local lines
6+
if case.property == 'consistency'
7+
lines = {
8+
"encoded = encode #{quote case.input.string}",
9+
"decoded = decode encoded",
10+
"assert.are.equal #{quote case.expected}, decoded"
11+
}
12+
else
13+
lines = {
14+
"result = #{case.property} #{quote case.input.string}",
15+
"assert.are.equal #{quote case.expected}, result"
16+
}
17+
table.concat [indent line, level for line in *lines], '\n'
18+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[ad53b61b-6ffc-422f-81a6-61f7df92a231]
13+
description = "run-length encode a string -> empty string"
14+
15+
[52012823-b7e6-4277-893c-5b96d42f82de]
16+
description = "run-length encode a string -> single characters only are encoded without count"
17+
18+
[b7868492-7e3a-415f-8da3-d88f51f80409]
19+
description = "run-length encode a string -> string with no single characters"
20+
21+
[859b822b-6e9f-44d6-9c46-6091ee6ae358]
22+
description = "run-length encode a string -> single characters mixed with repeated characters"
23+
24+
[1b34de62-e152-47be-bc88-469746df63b3]
25+
description = "run-length encode a string -> multiple whitespace mixed in string"
26+
27+
[abf176e2-3fbd-40ad-bb2f-2dd6d4df721a]
28+
description = "run-length encode a string -> lowercase characters"
29+
30+
[7ec5c390-f03c-4acf-ac29-5f65861cdeb5]
31+
description = "run-length decode a string -> empty string"
32+
33+
[ad23f455-1ac2-4b0e-87d0-b85b10696098]
34+
description = "run-length decode a string -> single characters only"
35+
36+
[21e37583-5a20-4a0e-826c-3dee2c375f54]
37+
description = "run-length decode a string -> string with no single characters"
38+
39+
[1389ad09-c3a8-4813-9324-99363fba429c]
40+
description = "run-length decode a string -> single characters with repeated characters"
41+
42+
[3f8e3c51-6aca-4670-b86c-a213bf4706b0]
43+
description = "run-length decode a string -> multiple whitespace mixed in string"
44+
45+
[29f721de-9aad-435f-ba37-7662df4fb551]
46+
description = "run-length decode a string -> lowercase string"
47+
48+
[2a762efd-8695-4e04-b0d6-9736899fbc16]
49+
description = "encode and then decode -> encode followed by decode gives original string"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
encode: (plaintext) ->
3+
error 'Implement the encode function'
4+
5+
decode: (ciphertext) ->
6+
error 'Implement the decode function'
7+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import encode, decode from require 'run_length_encoding'
2+
3+
describe 'run-length-encoding', ->
4+
describe 'run-length encode a string', ->
5+
it 'empty string', ->
6+
result = encode ''
7+
assert.are.equal '', result
8+
9+
pending 'single characters only are encoded without count', ->
10+
result = encode 'XYZ'
11+
assert.are.equal 'XYZ', result
12+
13+
pending 'string with no single characters', ->
14+
result = encode 'AABBBCCCC'
15+
assert.are.equal '2A3B4C', result
16+
17+
pending 'single characters mixed with repeated characters', ->
18+
result = encode 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'
19+
assert.are.equal '12WB12W3B24WB', result
20+
21+
pending 'multiple whitespace mixed in string', ->
22+
result = encode ' hsqq qww '
23+
assert.are.equal '2 hs2q q2w2 ', result
24+
25+
pending 'lowercase characters', ->
26+
result = encode 'aabbbcccc'
27+
assert.are.equal '2a3b4c', result
28+
29+
describe 'run-length decode a string', ->
30+
pending 'empty string', ->
31+
result = decode ''
32+
assert.are.equal '', result
33+
34+
pending 'single characters only', ->
35+
result = decode 'XYZ'
36+
assert.are.equal 'XYZ', result
37+
38+
pending 'string with no single characters', ->
39+
result = decode '2A3B4C'
40+
assert.are.equal 'AABBBCCCC', result
41+
42+
pending 'single characters with repeated characters', ->
43+
result = decode '12WB12W3B24WB'
44+
assert.are.equal 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB', result
45+
46+
pending 'multiple whitespace mixed in string', ->
47+
result = decode '2 hs2q q2w2 '
48+
assert.are.equal ' hsqq qww ', result
49+
50+
pending 'lowercase string', ->
51+
result = decode '2a3b4c'
52+
assert.are.equal 'aabbbcccc', result
53+
54+
describe 'encode and then decode', ->
55+
pending 'encode followed by decode gives original string', ->
56+
encoded = encode 'zzz ZZ zZ'
57+
decoded = decode encoded
58+
assert.are.equal 'zzz ZZ zZ', decoded

0 commit comments

Comments
 (0)