Skip to content

Commit 5ae1674

Browse files
Add run-length-encoding exercise (#49)
1 parent 8324420 commit 5ae1674

File tree

7 files changed

+222
-0
lines changed

7 files changed

+222
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,14 @@
334334
"prerequisites": [],
335335
"difficulty": 5
336336
},
337+
{
338+
"slug": "run-length-encoding",
339+
"name": "Run-Length Encoding",
340+
"uuid": "9b14d6e1-bd0e-4450-817f-e6e2c3958a3d",
341+
"practices": [],
342+
"prerequisites": [],
343+
"difficulty": 5
344+
},
337345
{
338346
"slug": "variable-length-quantity",
339347
"name": "Variable Length Quantity",
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+
"keiravillekode"
4+
],
5+
"files": {
6+
"solution": [
7+
"run_length_encoding.fut"
8+
],
9+
"test": [
10+
"test.fut"
11+
],
12+
"example": [
13+
".meta/example.fut"
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: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
def encode [n] (string: [n]u8): []u8 =
2+
let (a, i, _) = loop (a, i, k) = (replicate n '\0', n, n) while k > 0 do
3+
let c = string[k - 1]
4+
let j = loop j = k - 1 while j > 0 && string[j - 1] == c do
5+
j - 1
6+
7+
-- Run-length encode the run from `j` (inclusive) to `k` (exclusive) of the character c
8+
let a2 = a with [i - 1] = c
9+
let i2 = i - 1
10+
in
11+
if k - j == 1 then (a2, i2, j) else
12+
let (a3, i3, _) = loop (a3, i3, number) = (a2, i2, k - j) while number > 0 do
13+
(a3 with [i3 - 1] = '0' + u8.i64 (number % 10), i3 - 1, number / 10)
14+
in (a3, i3, j)
15+
in
16+
a[i:]
17+
18+
def decode_length (string: []u8): i64 =
19+
let (i, _) = loop (i, number) = (0, 0) for c in string do
20+
if c >= '0' && c <= '9' then (i, number * 10 + i64.u8 c - '0') else
21+
if number == 0 then (i + 1, 0) else
22+
(i + number, 0)
23+
in
24+
i
25+
26+
def decode [n] (string: [n]u8): []u8 =
27+
let (a, _, _) = loop (a, i, number) = (replicate (decode_length string) '\0', 0, 0) for c in string do
28+
if c >= '0' && c <= '9' then (a, i, number * 10 + i64.u8 c - '0') else
29+
if number == 0 then (a with [i] = c, i + 1, 0) else
30+
let (a2, i2, number2) = loop (a2, i2, number2) = (a, i, number) while number2 > 0 do
31+
(a2 with [i2] = c, i2 + 1, number2 - 1)
32+
in
33+
(a2, i2, number2)
34+
in
35+
a
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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
def encode (string: []u8): []u8 = ???
2+
3+
def decode (string: []u8): []u8 = ???
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import "run_length_encoding"
2+
3+
-- empty string
4+
-- ==
5+
-- entry: test_encode
6+
-- input { "" }
7+
-- output { "" }
8+
9+
-- single characters only are encoded without count
10+
-- ==
11+
-- entry: test_encode
12+
-- input { "XYZ" }
13+
-- output { "XYZ" }
14+
15+
-- string with no single characters
16+
-- ==
17+
-- entry: test_encode
18+
-- input { "AABBBCCCC" }
19+
-- output { "2A3B4C" }
20+
21+
-- single characters mixed with repeated characters
22+
-- ==
23+
-- entry: test_encode
24+
-- input { "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" }
25+
-- output { "12WB12W3B24WB" }
26+
27+
-- multiple whitespace mixed in string
28+
-- ==
29+
-- entry: test_encode
30+
-- input { " hsqq qww " }
31+
-- output { "2 hs2q q2w2 " }
32+
33+
-- lowercase characters
34+
-- ==
35+
-- entry: test_encode
36+
-- input { "aabbbcccc" }
37+
-- output { "2a3b4c" }
38+
39+
-- empty string
40+
-- ==
41+
-- entry: test_decode
42+
-- input { "" }
43+
-- output { "" }
44+
45+
-- single characters only
46+
-- ==
47+
-- entry: test_decode
48+
-- input { "XYZ" }
49+
-- output { "XYZ" }
50+
51+
-- string with no single characters
52+
-- ==
53+
-- entry: test_decode
54+
-- input { "2A3B4C" }
55+
-- output { "AABBBCCCC" }
56+
57+
-- single characters with repeated characters
58+
-- ==
59+
-- entry: test_decode
60+
-- input { "12WB12W3B24WB" }
61+
-- output { "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" }
62+
63+
-- multiple whitespace mixed in string
64+
-- ==
65+
-- entry: test_decode
66+
-- input { "2 hs2q q2w2 " }
67+
-- output { " hsqq qww " }
68+
69+
-- lowercase string
70+
-- ==
71+
-- entry: test_decode
72+
-- input { "2a3b4c" }
73+
-- output { "aabbbcccc" }
74+
75+
-- encode followed by decode gives original string
76+
-- ==
77+
-- entry: test_consistency
78+
-- input { "zzz ZZ zZ" }
79+
-- output { "zzz ZZ zZ" }
80+
81+
entry test_encode (string: []u8): []u8 =
82+
encode string
83+
84+
entry test_decode (string: []u8): []u8 =
85+
decode string
86+
87+
entry test_consistency (string: []u8): []u8 =
88+
decode (encode string)

0 commit comments

Comments
 (0)