Skip to content

Commit 6d07876

Browse files
Add sublist exercise (#82)
1 parent a8a896a commit 6d07876

File tree

8 files changed

+262
-0
lines changed

8 files changed

+262
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,14 @@
233233
"prerequisites": [],
234234
"difficulty": 3
235235
},
236+
{
237+
"slug": "sublist",
238+
"name": "Sublist",
239+
"uuid": "05c30dae-f899-4093-9382-45be2a2c455c",
240+
"practices": [],
241+
"prerequisites": [],
242+
"difficulty": 3
243+
},
236244
{
237245
"slug": "sum-of-multiples",
238246
"name": "Sum of Multiples",
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Instructions
2+
3+
Given any two lists `A` and `B`, determine if:
4+
5+
- List `A` is equal to list `B`; or
6+
- List `A` contains list `B` (`A` is a superlist of `B`); or
7+
- List `A` is contained by list `B` (`A` is a sublist of `B`); or
8+
- None of the above is true, thus lists `A` and `B` are unequal
9+
10+
Specifically, list `A` is equal to list `B` if both lists have the same values in the same order.
11+
List `A` is a superlist of `B` if `A` contains a contiguous sub-sequence of values equal to `B`.
12+
List `A` is a sublist of `B` if `B` contains a contiguous sub-sequence of values equal to `A`.
13+
14+
Examples:
15+
16+
- If `A = []` and `B = []` (both lists are empty), then `A` and `B` are equal
17+
- If `A = [1, 2, 3]` and `B = []`, then `A` is a superlist of `B`
18+
- If `A = []` and `B = [1, 2, 3]`, then `A` is a sublist of `B`
19+
- If `A = [1, 2, 3]` and `B = [1, 2, 3, 4, 5]`, then `A` is a sublist of `B`
20+
- If `A = [3, 4, 5]` and `B = [1, 2, 3, 4, 5]`, then `A` is a sublist of `B`
21+
- If `A = [3, 4]` and `B = [1, 2, 3, 4, 5]`, then `A` is a sublist of `B`
22+
- If `A = [1, 2, 3]` and `B = [1, 2, 3]`, then `A` and `B` are equal
23+
- If `A = [1, 2, 3, 4, 5]` and `B = [2, 3, 4]`, then `A` is a superlist of `B`
24+
- If `A = [1, 2, 4]` and `B = [1, 2, 3, 4, 5]`, then `A` and `B` are unequal
25+
- If `A = [1, 2, 3]` and `B = [1, 3, 2]`, then `A` and `B` are unequal
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"authors": [
3+
"keiravillekode"
4+
],
5+
"files": {
6+
"solution": [
7+
"sublist.fut"
8+
],
9+
"test": [
10+
"test.fut"
11+
],
12+
"example": [
13+
".meta/example.fut"
14+
]
15+
},
16+
"blurb": "Write a function to determine if a list is a sublist of another list."
17+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
type relation = #equal | #superlist | #sublist | #unequal
2+
3+
local def is_equal (list_one: []i32) (list_two: []i32): bool =
4+
let result = loop result = true for i < length list_one do
5+
result && list_one[i] == list_two[i]
6+
in
7+
result
8+
9+
local def is_sublist [m] [n] (list_one: [m]i32) (list_two: [n]i32): bool =
10+
let result = loop result = false for i in 0...(n - m) do
11+
result || is_equal list_one list_two[i:i + m]
12+
in
13+
result
14+
15+
def compare [m] [n] (list_one: [m]i32) (list_two: [n]i32): relation =
16+
if m < n && is_sublist list_one list_two then #sublist else
17+
if m > n && is_sublist list_two list_one then #superlist else
18+
if m == n && is_equal list_one list_two then #equal else
19+
#unequal
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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+
[97319c93-ebc5-47ab-a022-02a1980e1d29]
13+
description = "empty lists"
14+
15+
[de27dbd4-df52-46fe-a336-30be58457382]
16+
description = "empty list within non empty list"
17+
18+
[5487cfd1-bc7d-429f-ac6f-1177b857d4fb]
19+
description = "non empty list contains empty list"
20+
21+
[1f390b47-f6b2-4a93-bc23-858ba5dda9a6]
22+
description = "list equals itself"
23+
24+
[7ed2bfb2-922b-4363-ae75-f3a05e8274f5]
25+
description = "different lists"
26+
27+
[3b8a2568-6144-4f06-b0a1-9d266b365341]
28+
description = "false start"
29+
30+
[dc39ed58-6311-4814-be30-05a64bc8d9b1]
31+
description = "consecutive"
32+
33+
[d1270dab-a1ce-41aa-b29d-b3257241ac26]
34+
description = "sublist at start"
35+
36+
[81f3d3f7-4f25-4ada-bcdc-897c403de1b6]
37+
description = "sublist in middle"
38+
39+
[43bcae1e-a9cf-470e-923e-0946e04d8fdd]
40+
description = "sublist at end"
41+
42+
[76cf99ed-0ff0-4b00-94af-4dfb43fe5caa]
43+
description = "at start of superlist"
44+
45+
[b83989ec-8bdf-4655-95aa-9f38f3e357fd]
46+
description = "in middle of superlist"
47+
48+
[26f9f7c3-6cf6-4610-984a-662f71f8689b]
49+
description = "at end of superlist"
50+
51+
[0a6db763-3588-416a-8f47-76b1cedde31e]
52+
description = "first list missing element from second list"
53+
54+
[83ffe6d8-a445-4a3c-8795-1e51a95e65c3]
55+
description = "second list missing element from first list"
56+
57+
[7bc76cb8-5003-49ca-bc47-cdfbe6c2bb89]
58+
description = "first list missing additional digits from second list"
59+
60+
[0d7ee7c1-0347-45c8-9ef5-b88db152b30b]
61+
description = "order matters to a list"
62+
63+
[5f47ce86-944e-40f9-9f31-6368aad70aa6]
64+
description = "same digits but different numbers"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
type relation = #equal | #superlist | #sublist | #unequal
2+
3+
def compare (list_one: []i32) (list_two: []i32): relation = ???

exercises/practice/sublist/test.fut

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import "sublist"
2+
3+
-- empty lists
4+
-- ==
5+
-- input { empty([0]i32) empty([0]i32) }
6+
-- output { "equal" }
7+
8+
-- empty list within non empty list
9+
-- ==
10+
-- input { empty([0]i32) [1, 2, 3] }
11+
-- output { "sublist" }
12+
13+
-- non empty list contains empty list
14+
-- ==
15+
-- input { [1, 2, 3] empty([0]i32) }
16+
-- output { "superlist" }
17+
18+
-- list equals itself
19+
-- ==
20+
-- input { [1, 2, 3] [1, 2, 3] }
21+
-- output { "equal" }
22+
23+
-- different lists
24+
-- ==
25+
-- input { [1, 2, 3] [2, 3, 4] }
26+
-- output { "unequal" }
27+
28+
-- false start
29+
-- ==
30+
-- input { [1, 2, 5] [0, 1, 2, 3, 1, 2, 5, 6] }
31+
-- output { "sublist" }
32+
33+
-- consecutive
34+
-- ==
35+
-- input { [1, 1, 2] [0, 1, 1, 1, 2, 1, 2] }
36+
-- output { "sublist" }
37+
38+
-- sublist at start
39+
-- ==
40+
-- input { [0, 1, 2] [0, 1, 2, 3, 4, 5] }
41+
-- output { "sublist" }
42+
43+
-- sublist in middle
44+
-- ==
45+
-- input { [2, 3, 4] [0, 1, 2, 3, 4, 5] }
46+
-- output { "sublist" }
47+
48+
-- sublist at end
49+
-- ==
50+
-- input { [3, 4, 5] [0, 1, 2, 3, 4, 5] }
51+
-- output { "sublist" }
52+
53+
-- at start of superlist
54+
-- ==
55+
-- input { [0, 1, 2, 3, 4, 5] [0, 1, 2] }
56+
-- output { "superlist" }
57+
58+
-- in middle of superlist
59+
-- ==
60+
-- input { [0, 1, 2, 3, 4, 5] [2, 3] }
61+
-- output { "superlist" }
62+
63+
-- at end of superlist
64+
-- ==
65+
-- input { [0, 1, 2, 3, 4, 5] [3, 4, 5] }
66+
-- output { "superlist" }
67+
68+
-- first list missing element from second list
69+
-- ==
70+
-- input { [1, 3] [1, 2, 3] }
71+
-- output { "unequal" }
72+
73+
-- second list missing element from first list
74+
-- ==
75+
-- input { [1, 2, 3] [1, 3] }
76+
-- output { "unequal" }
77+
78+
-- first list missing additional digits from second list
79+
-- ==
80+
-- input { [1, 2] [1, 22] }
81+
-- output { "unequal" }
82+
83+
-- order matters to a list
84+
-- ==
85+
-- input { [1, 2, 3] [3, 2, 1] }
86+
-- output { "unequal" }
87+
88+
-- same digits but different numbers
89+
-- ==
90+
-- input { [1, 0, 1] [10, 1] }
91+
-- output { "unequal" }
92+
93+
local def name (r: relation): []u8 =
94+
match r
95+
case #equal -> "equal"
96+
case #superlist -> "superlist"
97+
case #sublist -> "sublist"
98+
case #unequal -> "unequal"
99+
100+
def main (list_one: []i32) (list_two: []i32): []u8 =
101+
name (compare list_one list_two)

generators/exercises/sublist.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
def gen_test_case(prop, description, inp, expected, f):
2+
def serialize_list(values):
3+
if values == []:
4+
return "empty([0]i32)"
5+
return str(values)
6+
7+
list_one = serialize_list(inp["listOne"])
8+
list_two = serialize_list(inp["listTwo"])
9+
10+
f.write(f"-- {description}\n")
11+
f.write("-- ==\n")
12+
f.write("-- input {" + f" {list_one} {list_two} " + "}\n")
13+
f.write('-- output { "' + expected + '" }\n\n')
14+
15+
16+
def gen_main(f):
17+
f.write("local def name (r: relation): []u8 =\n")
18+
f.write(" match r\n")
19+
f.write(' case #equal -> "equal"\n')
20+
f.write(' case #superlist -> "superlist"\n')
21+
f.write(' case #sublist -> "sublist"\n')
22+
f.write(' case #unequal -> "unequal"\n\n')
23+
24+
f.write("def main (list_one: []i32) (list_two: []i32): []u8 =\n")
25+
f.write(" name (compare list_one list_two)\n")

0 commit comments

Comments
 (0)