Skip to content

Commit 14235a0

Browse files
Add sublist exercise (#440)
1 parent f646a72 commit 14235a0

File tree

7 files changed

+311
-1
lines changed

7 files changed

+311
-1
lines changed

config.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,17 @@
214214
],
215215
"difficulty": 1
216216
},
217+
{
218+
"slug": "sublist",
219+
"name": "Sublist",
220+
"uuid": "a2c7d511-7f80-410b-923f-0343d0770d81",
221+
"practices": [],
222+
"prerequisites": [],
223+
"difficulty": 3
224+
},
217225
{
218226
"slug": "run-length-encoding",
219-
"name": "Run Length Encoding",
227+
"name": "Run-Length Encoding",
220228
"uuid": "71e5d918-6327-442a-98e8-3f9560b1ecd9",
221229
"practices": [],
222230
"prerequisites": [],
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.zig"
8+
],
9+
"test": [
10+
"test_sublist.zig"
11+
],
12+
"example": [
13+
".meta/example.zig"
14+
]
15+
},
16+
"blurb": "Write a function to determine if a list is a sublist of another list."
17+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
pub const Relation = enum {
2+
equal,
3+
sublist,
4+
superlist,
5+
unequal,
6+
};
7+
8+
fn isEqual(list_one: []const i32, list_two: []const i32) bool {
9+
if (list_one.len != list_two.len) {
10+
return false;
11+
}
12+
13+
for (0..(list_one.len)) |i| {
14+
if (list_one[i] != list_two[i]) {
15+
return false;
16+
}
17+
}
18+
19+
return true;
20+
}
21+
22+
fn isSublist(list_one: []const i32, list_two: []const i32) bool {
23+
return isEqual(list_one, list_two[0..(list_one.len)]) or ((list_one.len < list_two.len) and isSublist(list_one, list_two[1..]));
24+
}
25+
26+
pub fn compare(list_one: []const i32, list_two: []const i32) Relation {
27+
if (isEqual(list_one, list_two)) {
28+
return .equal;
29+
} else if (list_one.len <= list_two.len and isSublist(list_one, list_two)) {
30+
return .sublist;
31+
} else if (list_two.len <= list_one.len and isSublist(list_two, list_one)) {
32+
return .superlist;
33+
} else {
34+
return .unequal;
35+
}
36+
}
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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
pub const Relation = enum {
2+
equal,
3+
sublist,
4+
superlist,
5+
unequal,
6+
};
7+
8+
pub fn compare(list_one: []const i32, list_two: []const i32) Relation {
9+
_ = list_one;
10+
_ = list_two;
11+
@compileError("please implement the compare function");
12+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
const std = @import("std");
2+
const testing = std.testing;
3+
4+
const sublist = @import("sublist.zig");
5+
6+
test "empty lists" {
7+
const list_one = &[_]i32{};
8+
const list_two = &[_]i32{};
9+
const expected = .equal;
10+
const actual = sublist.compare(list_one, list_two);
11+
try testing.expectEqual(expected, actual);
12+
}
13+
14+
test "empty list within non empty list" {
15+
const list_one = &[_]i32{};
16+
const list_two = &[_]i32{ 1, 2, 3 };
17+
const expected = .sublist;
18+
const actual = sublist.compare(list_one, list_two);
19+
try testing.expectEqual(expected, actual);
20+
}
21+
22+
test "non empty list contains empty list" {
23+
const list_one = &[_]i32{ 1, 2, 3 };
24+
const list_two = &[_]i32{};
25+
const expected = .superlist;
26+
const actual = sublist.compare(list_one, list_two);
27+
try testing.expectEqual(expected, actual);
28+
}
29+
30+
test "list equals itself" {
31+
const list_one = &[_]i32{ 1, 2, 3 };
32+
const list_two = &[_]i32{ 1, 2, 3 };
33+
const expected = .equal;
34+
const actual = sublist.compare(list_one, list_two);
35+
try testing.expectEqual(expected, actual);
36+
}
37+
38+
test "different lists" {
39+
const list_one = &[_]i32{ 1, 2, 3 };
40+
const list_two = &[_]i32{ 2, 3, 4 };
41+
const expected = .unequal;
42+
const actual = sublist.compare(list_one, list_two);
43+
try testing.expectEqual(expected, actual);
44+
}
45+
46+
test "false start" {
47+
const list_one = &[_]i32{ 1, 2, 5 };
48+
const list_two = &[_]i32{ 0, 1, 2, 3, 1, 2, 5, 6 };
49+
const expected = .sublist;
50+
const actual = sublist.compare(list_one, list_two);
51+
try testing.expectEqual(expected, actual);
52+
}
53+
54+
test "consecutive" {
55+
const list_one = &[_]i32{ 1, 1, 2 };
56+
const list_two = &[_]i32{ 0, 1, 1, 1, 2, 1, 2 };
57+
const expected = .sublist;
58+
const actual = sublist.compare(list_one, list_two);
59+
try testing.expectEqual(expected, actual);
60+
}
61+
62+
test "sublist at start" {
63+
const list_one = &[_]i32{ 0, 1, 2 };
64+
const list_two = &[_]i32{ 0, 1, 2, 3, 4, 5 };
65+
const expected = .sublist;
66+
const actual = sublist.compare(list_one, list_two);
67+
try testing.expectEqual(expected, actual);
68+
}
69+
70+
test "sublist in middle" {
71+
const list_one = &[_]i32{ 2, 3, 4 };
72+
const list_two = &[_]i32{ 0, 1, 2, 3, 4, 5 };
73+
const expected = .sublist;
74+
const actual = sublist.compare(list_one, list_two);
75+
try testing.expectEqual(expected, actual);
76+
}
77+
78+
test "sublist at end" {
79+
const list_one = &[_]i32{ 3, 4, 5 };
80+
const list_two = &[_]i32{ 0, 1, 2, 3, 4, 5 };
81+
const expected = .sublist;
82+
const actual = sublist.compare(list_one, list_two);
83+
try testing.expectEqual(expected, actual);
84+
}
85+
86+
test "at start of superlist" {
87+
const list_one = &[_]i32{ 0, 1, 2, 3, 4, 5 };
88+
const list_two = &[_]i32{ 0, 1, 2 };
89+
const expected = .superlist;
90+
const actual = sublist.compare(list_one, list_two);
91+
try testing.expectEqual(expected, actual);
92+
}
93+
94+
test "in middle of superlist" {
95+
const list_one = &[_]i32{ 0, 1, 2, 3, 4, 5 };
96+
const list_two = &[_]i32{ 2, 3 };
97+
const expected = .superlist;
98+
const actual = sublist.compare(list_one, list_two);
99+
try testing.expectEqual(expected, actual);
100+
}
101+
102+
test "at end of superlist" {
103+
const list_one = &[_]i32{ 0, 1, 2, 3, 4, 5 };
104+
const list_two = &[_]i32{ 3, 4, 5 };
105+
const expected = .superlist;
106+
const actual = sublist.compare(list_one, list_two);
107+
try testing.expectEqual(expected, actual);
108+
}
109+
110+
test "first list missing element from second list" {
111+
const list_one = &[_]i32{ 1, 3 };
112+
const list_two = &[_]i32{ 1, 2, 3 };
113+
const expected = .unequal;
114+
const actual = sublist.compare(list_one, list_two);
115+
try testing.expectEqual(expected, actual);
116+
}
117+
118+
test "second list missing element from first list" {
119+
const list_one = &[_]i32{ 1, 2, 3 };
120+
const list_two = &[_]i32{ 1, 3 };
121+
const expected = .unequal;
122+
const actual = sublist.compare(list_one, list_two);
123+
try testing.expectEqual(expected, actual);
124+
}
125+
126+
test "first list missing additional digits from second list" {
127+
const list_one = &[_]i32{ 1, 2 };
128+
const list_two = &[_]i32{ 1, 22 };
129+
const expected = .unequal;
130+
const actual = sublist.compare(list_one, list_two);
131+
try testing.expectEqual(expected, actual);
132+
}
133+
134+
test "order matters to a list" {
135+
const list_one = &[_]i32{ 1, 2, 3 };
136+
const list_two = &[_]i32{ 3, 2, 1 };
137+
const expected = .unequal;
138+
const actual = sublist.compare(list_one, list_two);
139+
try testing.expectEqual(expected, actual);
140+
}
141+
142+
test "same digits but different numbers" {
143+
const list_one = &[_]i32{ 1, 0, 1 };
144+
const list_two = &[_]i32{ 10, 1 };
145+
const expected = .unequal;
146+
const actual = sublist.compare(list_one, list_two);
147+
try testing.expectEqual(expected, actual);
148+
}

0 commit comments

Comments
 (0)