Skip to content

Commit 2c11a07

Browse files
Add series exercise (#112)
1 parent 6757831 commit 2c11a07

File tree

9 files changed

+174
-0
lines changed

9 files changed

+174
-0
lines changed

bin/add-practice-exercise

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ fi
7171
exercise_dir="exercises/practice/${slug}"
7272
files=$(jq -r --arg dir "${exercise_dir}" '.files | to_entries | map({key: .key, value: (.value | map("'"'"'" + $dir + "/" + . + "'"'"'") | join(" and "))}) | from_entries' "${exercise_dir}/.meta/config.json")
7373

74+
touch "generators/exercises/${slug//-/_}.py"
75+
7476
cat << NEXT_STEPS
7577
7678
Your next steps are:

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,14 @@
385385
"prerequisites": [],
386386
"difficulty": 4
387387
},
388+
{
389+
"slug": "series",
390+
"name": "Series",
391+
"uuid": "4f4ae55e-e180-47d9-90bf-be104a3f7b31",
392+
"practices": [],
393+
"prerequisites": [],
394+
"difficulty": 4
395+
},
388396
{
389397
"slug": "sieve",
390398
"name": "Sieve",
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Instructions
2+
3+
Given a string of digits, output all the contiguous substrings of length `n` in that string in the order that they appear.
4+
5+
For example, the string "49142" has the following 3-digit series:
6+
7+
- "491"
8+
- "914"
9+
- "142"
10+
11+
And the following 4-digit series:
12+
13+
- "4914"
14+
- "9142"
15+
16+
And if you ask for a 6-digit series from a 5-digit string, you deserve whatever you get.
17+
18+
Note that these series are only required to occupy _adjacent positions_ in the input;
19+
the digits need not be _numerically consecutive_.
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+
"series.fut"
8+
],
9+
"test": [
10+
"test.fut"
11+
],
12+
"example": [
13+
".meta/example.fut"
14+
]
15+
},
16+
"blurb": "Given a string of digits, output all the contiguous substrings of length `n` in that string.",
17+
"source": "A subset of the Problem 8 at Project Euler",
18+
"source_url": "https://projecteuler.net/problem=8"
19+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def slices (series: []u8) (sliceLength: i64): [][]u8 =
2+
let seriesLength = length series
3+
let n = seriesLength + 1 - sliceLength
4+
let slice = \i -> series[i:i + sliceLength] :> [sliceLength]u8
5+
in
6+
assert (1 <= n && n <= seriesLength) (tabulate n slice)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
[7ae7a46a-d992-4c2a-9c15-a112d125ebad]
13+
description = "slices of one from one"
14+
15+
[3143b71d-f6a5-4221-aeae-619f906244d2]
16+
description = "slices of one from two"
17+
18+
[dbb68ff5-76c5-4ccd-895a-93dbec6d5805]
19+
description = "slices of two"
20+
21+
[19bbea47-c987-4e11-a7d1-e103442adf86]
22+
description = "slices of two overlap"
23+
24+
[8e17148d-ba0a-4007-a07f-d7f87015d84c]
25+
description = "slices can include duplicates"
26+
27+
[bd5b085e-f612-4f81-97a8-6314258278b0]
28+
description = "slices of a long series"
29+
30+
[6d235d85-46cf-4fae-9955-14b6efef27cd]
31+
description = "slice length is too large"
32+
33+
[d7957455-346d-4e47-8e4b-87ed1564c6d7]
34+
description = "slice length is way too large"
35+
36+
[d34004ad-8765-4c09-8ba1-ada8ce776806]
37+
description = "slice length cannot be zero"
38+
39+
[10ab822d-8410-470a-a85d-23fbeb549e54]
40+
description = "slice length cannot be negative"
41+
42+
[c7ed0812-0e4b-4bf3-99c4-28cbbfc246a2]
43+
description = "empty series is invalid"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def slices (series: []u8) (sliceLength: i64): [][]u8 = ???

exercises/practice/series/test.fut

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import "series"
2+
3+
-- slices of one from one
4+
-- ==
5+
-- input { "1" 1 }
6+
-- output { ["1"] }
7+
8+
-- slices of one from two
9+
-- ==
10+
-- input { "12" 1 }
11+
-- output { ["1", "2"] }
12+
13+
-- slices of two
14+
-- ==
15+
-- input { "35" 2 }
16+
-- output { ["35"] }
17+
18+
-- slices of two overlap
19+
-- ==
20+
-- input { "9142" 2 }
21+
-- output { ["91", "14", "42"] }
22+
23+
-- slices can include duplicates
24+
-- ==
25+
-- input { "777777" 3 }
26+
-- output { ["777", "777", "777", "777"] }
27+
28+
-- slices of a long series
29+
-- ==
30+
-- input { "918493904243" 5 }
31+
-- output { ["91849", "18493", "84939", "49390", "93904", "39042", "90424", "04243"] }
32+
33+
-- slice length is too large
34+
-- ==
35+
-- input { "12345" 6 }
36+
-- error: Error*
37+
38+
-- slice length is way too large
39+
-- ==
40+
-- input { "12345" 42 }
41+
-- error: Error*
42+
43+
-- slice length cannot be zero
44+
-- ==
45+
-- input { "12345" 0 }
46+
-- error: Error*
47+
48+
-- slice length cannot be negative
49+
-- ==
50+
-- input { "123" -1 }
51+
-- error: Error*
52+
53+
-- empty series is invalid
54+
-- ==
55+
-- input { "" 1 }
56+
-- error: Error*
57+
58+
let main (series: []u8) (sliceLength: i32): [][]u8 =
59+
slices series (i64.i32 sliceLength)

generators/exercises/series.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
def gen_test_case(prop, description, inp, expected, f):
2+
series = inp["series"]
3+
sliceLength = inp["sliceLength"]
4+
5+
f.write(f"-- {description}\n")
6+
f.write("-- ==\n")
7+
f.write(f'-- input {{ "{series}" {sliceLength} }}\n')
8+
if isinstance(expected, dict):
9+
f.write("-- error: Error*\n\n")
10+
else:
11+
expected = str(expected).replace("'", '"')
12+
f.write(f"-- output {{ {expected} }}\n\n")
13+
14+
15+
def gen_main(f):
16+
f.write("let main (series: []u8) (sliceLength: i32): [][]u8 =\n")
17+
f.write(" slices series (i64.i32 sliceLength)\n")

0 commit comments

Comments
 (0)