Skip to content

Commit 5a76d03

Browse files
authored
Update list-ops tests (#588)
1 parent 865cb9f commit 5a76d03

File tree

5 files changed

+347
-95
lines changed

5 files changed

+347
-95
lines changed
Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,74 @@
1-
local function reduce(xs, value, f)
1+
local function append(xs, ys)
2+
local result = {}
23
for _, x in ipairs(xs) do
3-
value = f(x, value)
4+
table.insert(result, x)
5+
end
6+
for _, y in ipairs(ys) do
7+
table.insert(result, y)
8+
end
9+
return result
10+
end
11+
12+
local function concat(...)
13+
local result = {}
14+
for _, list in ipairs({ ... }) do
15+
for _, item in ipairs(list) do
16+
table.insert(result, item)
17+
end
18+
end
19+
return result
20+
end
21+
22+
local function length(xs)
23+
local count = 0
24+
for _ in ipairs(xs) do
25+
count = count + 1
26+
end
27+
return count
28+
end
29+
30+
local function reverse(xs)
31+
local result = {}
32+
for i = #xs, 1, -1 do
33+
table.insert(result, xs[i])
34+
end
35+
return result
36+
end
37+
38+
local function foldl(xs, value, f)
39+
for _, x in ipairs(xs) do
40+
value = f(value, x)
441
end
542
return value
643
end
744

45+
local function foldr(xs, value, f)
46+
return foldl(reverse(xs), value, f)
47+
end
48+
849
local function map(xs, f)
9-
return reduce(xs, {}, function(x, acc)
50+
return foldl(xs, {}, function(acc, x)
1051
table.insert(acc, f(x))
1152
return acc
1253
end)
1354
end
1455

1556
local function filter(xs, pred)
16-
return reduce(xs, {}, function(x, acc)
57+
return foldl(xs, {}, function(acc, x)
1758
if pred(x) then
1859
table.insert(acc, x)
1960
end
2061
return acc
2162
end)
2263
end
2364

24-
return { map = map, reduce = reduce, filter = filter }
65+
return {
66+
append = append,
67+
concat = concat,
68+
length = length,
69+
reverse = reverse,
70+
map = map,
71+
foldl = foldl,
72+
foldr = foldr,
73+
filter = filter
74+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
local function map(t, f)
2+
local result = {}
3+
for i, v in ipairs(t) do
4+
result[i] = f(v)
5+
end
6+
return result
7+
end
8+
9+
local function render_list(list)
10+
if type(list) ~= 'table' then
11+
return list
12+
end
13+
14+
return '{' .. table.concat(map(list, render_list), ', ') .. '}'
15+
end
16+
17+
local function render_function(s)
18+
s = s:gsub('modulo', '%%')
19+
local args, body = s:match('^(.+)%s*->%s*(.+)$')
20+
return 'function' .. args .. ' return ' .. body .. ' end'
21+
end
22+
23+
return {
24+
module_name = 'list_ops',
25+
26+
generate_test = function(case)
27+
if case.input.lists then
28+
local template = [[
29+
local expected = %s
30+
local actual = list_ops.%s(%s)
31+
assert.are.same(expected, actual)]]
32+
33+
return template:format(render_list(case.expected), case.property,
34+
render_list(table.concat(map(case.input.lists, render_list), ', ')))
35+
elseif case.input.list1 and case.input.list2 then
36+
local template = [[
37+
local expected = %s
38+
local actual = list_ops.%s(%s, %s)
39+
assert.are.same(expected, actual)]]
40+
41+
return template:format(render_list(case.expected), case.property, render_list(case.input.list1),
42+
render_list(case.input.list2))
43+
elseif case.input.list and case.input['function'] and case.input.initial then
44+
local template = [[
45+
local expected = %s
46+
local actual = list_ops.%s(%s, %s, %s)
47+
assert.are.same(expected, actual)]]
48+
49+
return template:format(render_list(case.expected), case.property, render_list(case.input.list),
50+
render_list(case.input.initial), render_function(case.input['function']))
51+
elseif case.input.list and case.input['function'] then
52+
local template = [[
53+
local expected = %s
54+
local actual = list_ops.%s(%s, %s)
55+
assert.are.same(expected, actual)]]
56+
57+
return template:format(render_list(case.expected), case.property, render_list(case.input.list),
58+
render_function(case.input['function']))
59+
elseif case.input.list then
60+
local template = [[
61+
local expected = %s
62+
local actual = list_ops.%s(%s)
63+
assert.are.same(expected, actual)]]
64+
65+
return template:format(render_list(case.expected), case.property, render_list(case.input.list))
66+
else
67+
error('Unhandled case')
68+
end
69+
end
70+
}
Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,103 @@
1-
# This is an auto-generated file. Regular comments will be removed when this
2-
# file is regenerated. Regenerating will not touch any manually added keys,
3-
# so comments can be added in a "comment" key.
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.
411

512
[485b9452-bf94-40f7-a3db-c3cf4850066a]
6-
description = "empty lists"
13+
description = "append entries to a list and return the new list -> empty lists"
714

815
[2c894696-b609-4569-b149-8672134d340a]
9-
description = "list to empty list"
16+
description = "append entries to a list and return the new list -> list to empty list"
1017

1118
[71dcf5eb-73ae-4a0e-b744-a52ee387922f]
12-
description = "non-empty lists"
19+
description = "append entries to a list and return the new list -> non-empty lists"
1320

1421
[28444355-201b-4af2-a2f6-5550227bde21]
15-
description = "empty list"
22+
description = "concatenate a list of lists -> empty list"
1623

1724
[331451c1-9573-42a1-9869-2d06e3b389a9]
18-
description = "list of lists"
25+
description = "concatenate a list of lists -> list of lists"
1926

2027
[d6ecd72c-197f-40c3-89a4-aa1f45827e09]
21-
description = "list of nested lists"
28+
description = "concatenate a list of lists -> list of nested lists"
2229

2330
[0524fba8-3e0f-4531-ad2b-f7a43da86a16]
24-
description = "empty list"
31+
description = "filter list returning only values that satisfy the filter function -> empty list"
2532

2633
[88494bd5-f520-4edb-8631-88e415b62d24]
27-
description = "non-empty list"
34+
description = "filter list returning only values that satisfy the filter function -> non-empty list"
2835

2936
[1cf0b92d-8d96-41d5-9c21-7b3c37cb6aad]
30-
description = "empty list"
37+
description = "returns the length of a list -> empty list"
3138

3239
[d7b8d2d9-2d16-44c4-9a19-6e5f237cb71e]
33-
description = "non-empty list"
40+
description = "returns the length of a list -> non-empty list"
3441

3542
[c0bc8962-30e2-4bec-9ae4-668b8ecd75aa]
36-
description = "empty list"
43+
description = "return a list of elements whose values equal the list value transformed by the mapping function -> empty list"
3744

3845
[11e71a95-e78b-4909-b8e4-60cdcaec0e91]
39-
description = "non-empty list"
46+
description = "return a list of elements whose values equal the list value transformed by the mapping function -> non-empty list"
4047

4148
[613b20b7-1873-4070-a3a6-70ae5f50d7cc]
42-
description = "empty list"
49+
description = "folds (reduces) the given list from the left with a function -> empty list"
50+
include = false
4351

4452
[e56df3eb-9405-416a-b13a-aabb4c3b5194]
45-
description = "direction independent function applied to non-empty list"
53+
description = "folds (reduces) the given list from the left with a function -> direction independent function applied to non-empty list"
54+
include = false
4655

4756
[d2cf5644-aee1-4dfc-9b88-06896676fe27]
48-
description = "direction dependent function applied to non-empty list"
57+
description = "folds (reduces) the given list from the left with a function -> direction dependent function applied to non-empty list"
58+
include = false
59+
60+
[36549237-f765-4a4c-bfd9-5d3a8f7b07d2]
61+
description = "folds (reduces) the given list from the left with a function -> empty list"
62+
reimplements = "613b20b7-1873-4070-a3a6-70ae5f50d7cc"
63+
64+
[7a626a3c-03ec-42bc-9840-53f280e13067]
65+
description = "folds (reduces) the given list from the left with a function -> direction independent function applied to non-empty list"
66+
reimplements = "e56df3eb-9405-416a-b13a-aabb4c3b5194"
67+
68+
[d7fcad99-e88e-40e1-a539-4c519681f390]
69+
description = "folds (reduces) the given list from the left with a function -> direction dependent function applied to non-empty list"
70+
reimplements = "d2cf5644-aee1-4dfc-9b88-06896676fe27"
4971

5072
[aeb576b9-118e-4a57-a451-db49fac20fdc]
51-
description = "empty list"
73+
description = "folds (reduces) the given list from the right with a function -> empty list"
74+
include = false
5275

5376
[c4b64e58-313e-4c47-9c68-7764964efb8e]
54-
description = "direction independent function applied to non-empty list"
77+
description = "folds (reduces) the given list from the right with a function -> direction independent function applied to non-empty list"
78+
include = false
5579

5680
[be396a53-c074-4db3-8dd6-f7ed003cce7c]
57-
description = "direction dependent function applied to non-empty list"
81+
description = "folds (reduces) the given list from the right with a function -> direction dependent function applied to non-empty list"
82+
include = false
83+
84+
[17214edb-20ba-42fc-bda8-000a5ab525b0]
85+
description = "folds (reduces) the given list from the right with a function -> empty list"
86+
reimplements = "aeb576b9-118e-4a57-a451-db49fac20fdc"
87+
88+
[e1c64db7-9253-4a3d-a7c4-5273b9e2a1bd]
89+
description = "folds (reduces) the given list from the right with a function -> direction independent function applied to non-empty list"
90+
reimplements = "c4b64e58-313e-4c47-9c68-7764964efb8e"
91+
92+
[8066003b-f2ff-437e-9103-66e6df474844]
93+
description = "folds (reduces) the given list from the right with a function -> direction dependent function applied to non-empty list"
94+
reimplements = "be396a53-c074-4db3-8dd6-f7ed003cce7c"
5895

5996
[94231515-050e-4841-943d-d4488ab4ee30]
60-
description = "empty list"
97+
description = "reverse the elements of the list -> empty list"
6198

6299
[fcc03d1e-42e0-4712-b689-d54ad761f360]
63-
description = "non-empty list"
100+
description = "reverse the elements of the list -> non-empty list"
64101

65102
[40872990-b5b8-4cb8-9085-d91fc0d05d26]
66-
description = "list of lists is not flattened"
103+
description = "reverse the elements of the list -> list of lists is not flattened"
Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,42 @@
1-
local function reduce(xs, value, f)
1+
local function append(xs, ys)
2+
3+
end
4+
5+
local function concat(...)
6+
7+
end
8+
9+
local function length(xs)
10+
11+
end
12+
13+
local function reverse(xs)
14+
15+
end
16+
17+
local function foldl(xs, value, f)
18+
19+
end
20+
21+
local function foldr(xs, value, f)
22+
223
end
324

425
local function map(xs, f)
26+
527
end
628

729
local function filter(xs, pred)
30+
831
end
932

10-
return { map = map, reduce = reduce, filter = filter }
33+
return {
34+
append = append,
35+
concat = concat,
36+
length = length,
37+
reverse = reverse,
38+
map = map,
39+
foldl = foldl,
40+
foldr = foldr,
41+
filter = filter
42+
}

0 commit comments

Comments
 (0)