From 5b98df40e931884f044d5176fc19c1ecdfb3e47d Mon Sep 17 00:00:00 2001 From: Norbiox <norbertchmiel.it@gmail.com> Date: Thu, 25 Jan 2024 15:17:47 +0100 Subject: [PATCH 01/24] add list-ops exercise configuration --- config.json | 8 ++ .../practice/list-ops/.docs/instructions.md | 19 ++++ exercises/practice/list-ops/.meta/config.json | 17 +++ exercises/practice/list-ops/.meta/example.nim | 0 exercises/practice/list-ops/.meta/tests.toml | 106 ++++++++++++++++++ exercises/practice/list-ops/list_ops.nim | 0 exercises/practice/list-ops/test_list_ops.nim | 0 7 files changed, 150 insertions(+) create mode 100644 exercises/practice/list-ops/.docs/instructions.md create mode 100644 exercises/practice/list-ops/.meta/config.json create mode 100644 exercises/practice/list-ops/.meta/example.nim create mode 100644 exercises/practice/list-ops/.meta/tests.toml create mode 100644 exercises/practice/list-ops/list_ops.nim create mode 100644 exercises/practice/list-ops/test_list_ops.nim diff --git a/config.json b/config.json index 32448b50..381d84fd 100644 --- a/config.json +++ b/config.json @@ -979,6 +979,14 @@ "events", "reactive_programming" ] + }, + { + "slug": "list-ops", + "name": "List Ops", + "uuid": "779343ba-9b40-4d43-b696-2267c4eecde0", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/list-ops/.docs/instructions.md b/exercises/practice/list-ops/.docs/instructions.md new file mode 100644 index 00000000..ebc5dffe --- /dev/null +++ b/exercises/practice/list-ops/.docs/instructions.md @@ -0,0 +1,19 @@ +# Instructions + +Implement basic list operations. + +In functional languages list operations like `length`, `map`, and `reduce` are very common. +Implement a series of basic list operations, without using existing functions. + +The precise number and names of the operations to be implemented will be track dependent to avoid conflicts with existing names, but the general operations you will implement include: + +- `append` (_given two lists, add all items in the second list to the end of the first list_); +- `concatenate` (_given a series of lists, combine all items in all lists into one flattened list_); +- `filter` (_given a predicate and a list, return the list of all items for which `predicate(item)` is True_); +- `length` (_given a list, return the total number of items within it_); +- `map` (_given a function and a list, return the list of the results of applying `function(item)` on all items_); +- `foldl` (_given a function, a list, and initial accumulator, fold (reduce) each item into the accumulator from the left_); +- `foldr` (_given a function, a list, and an initial accumulator, fold (reduce) each item into the accumulator from the right_); +- `reverse` (_given a list, return a list with all the original items, but in reversed order_). + +Note, the ordering in which arguments are passed to the fold functions (`foldl`, `foldr`) is significant. diff --git a/exercises/practice/list-ops/.meta/config.json b/exercises/practice/list-ops/.meta/config.json new file mode 100644 index 00000000..67415bc3 --- /dev/null +++ b/exercises/practice/list-ops/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": [ + "Norbiox" + ], + "files": { + "solution": [ + "list_ops.nim" + ], + "test": [ + "test_list_ops.nim" + ], + "example": [ + ".meta/example.nim" + ] + }, + "blurb": "Implement basic list operations." +} diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim new file mode 100644 index 00000000..e69de29b diff --git a/exercises/practice/list-ops/.meta/tests.toml b/exercises/practice/list-ops/.meta/tests.toml new file mode 100644 index 00000000..08b1edc0 --- /dev/null +++ b/exercises/practice/list-ops/.meta/tests.toml @@ -0,0 +1,106 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[485b9452-bf94-40f7-a3db-c3cf4850066a] +description = "append entries to a list and return the new list -> empty lists" + +[2c894696-b609-4569-b149-8672134d340a] +description = "append entries to a list and return the new list -> list to empty list" + +[e842efed-3bf6-4295-b371-4d67a4fdf19c] +description = "append entries to a list and return the new list -> empty list to list" + +[71dcf5eb-73ae-4a0e-b744-a52ee387922f] +description = "append entries to a list and return the new list -> non-empty lists" + +[28444355-201b-4af2-a2f6-5550227bde21] +description = "concatenate a list of lists -> empty list" + +[331451c1-9573-42a1-9869-2d06e3b389a9] +description = "concatenate a list of lists -> list of lists" + +[d6ecd72c-197f-40c3-89a4-aa1f45827e09] +description = "concatenate a list of lists -> list of nested lists" + +[0524fba8-3e0f-4531-ad2b-f7a43da86a16] +description = "filter list returning only values that satisfy the filter function -> empty list" + +[88494bd5-f520-4edb-8631-88e415b62d24] +description = "filter list returning only values that satisfy the filter function -> non-empty list" + +[1cf0b92d-8d96-41d5-9c21-7b3c37cb6aad] +description = "returns the length of a list -> empty list" + +[d7b8d2d9-2d16-44c4-9a19-6e5f237cb71e] +description = "returns the length of a list -> non-empty list" + +[c0bc8962-30e2-4bec-9ae4-668b8ecd75aa] +description = "return a list of elements whose values equal the list value transformed by the mapping function -> empty list" + +[11e71a95-e78b-4909-b8e4-60cdcaec0e91] +description = "return a list of elements whose values equal the list value transformed by the mapping function -> non-empty list" + +[613b20b7-1873-4070-a3a6-70ae5f50d7cc] +description = "folds (reduces) the given list from the left with a function -> empty list" +include = false + +[e56df3eb-9405-416a-b13a-aabb4c3b5194] +description = "folds (reduces) the given list from the left with a function -> direction independent function applied to non-empty list" +include = false + +[d2cf5644-aee1-4dfc-9b88-06896676fe27] +description = "folds (reduces) the given list from the left with a function -> direction dependent function applied to non-empty list" +include = false + +[36549237-f765-4a4c-bfd9-5d3a8f7b07d2] +description = "folds (reduces) the given list from the left with a function -> empty list" +reimplements = "613b20b7-1873-4070-a3a6-70ae5f50d7cc" + +[7a626a3c-03ec-42bc-9840-53f280e13067] +description = "folds (reduces) the given list from the left with a function -> direction independent function applied to non-empty list" +reimplements = "e56df3eb-9405-416a-b13a-aabb4c3b5194" + +[d7fcad99-e88e-40e1-a539-4c519681f390] +description = "folds (reduces) the given list from the left with a function -> direction dependent function applied to non-empty list" +reimplements = "d2cf5644-aee1-4dfc-9b88-06896676fe27" + +[aeb576b9-118e-4a57-a451-db49fac20fdc] +description = "folds (reduces) the given list from the right with a function -> empty list" +include = false + +[c4b64e58-313e-4c47-9c68-7764964efb8e] +description = "folds (reduces) the given list from the right with a function -> direction independent function applied to non-empty list" +include = false + +[be396a53-c074-4db3-8dd6-f7ed003cce7c] +description = "folds (reduces) the given list from the right with a function -> direction dependent function applied to non-empty list" +include = false + +[17214edb-20ba-42fc-bda8-000a5ab525b0] +description = "folds (reduces) the given list from the right with a function -> empty list" +reimplements = "aeb576b9-118e-4a57-a451-db49fac20fdc" + +[e1c64db7-9253-4a3d-a7c4-5273b9e2a1bd] +description = "folds (reduces) the given list from the right with a function -> direction independent function applied to non-empty list" +reimplements = "c4b64e58-313e-4c47-9c68-7764964efb8e" + +[8066003b-f2ff-437e-9103-66e6df474844] +description = "folds (reduces) the given list from the right with a function -> direction dependent function applied to non-empty list" +reimplements = "be396a53-c074-4db3-8dd6-f7ed003cce7c" + +[94231515-050e-4841-943d-d4488ab4ee30] +description = "reverse the elements of the list -> empty list" + +[fcc03d1e-42e0-4712-b689-d54ad761f360] +description = "reverse the elements of the list -> non-empty list" + +[40872990-b5b8-4cb8-9085-d91fc0d05d26] +description = "reverse the elements of the list -> list of lists is not flattened" diff --git a/exercises/practice/list-ops/list_ops.nim b/exercises/practice/list-ops/list_ops.nim new file mode 100644 index 00000000..e69de29b diff --git a/exercises/practice/list-ops/test_list_ops.nim b/exercises/practice/list-ops/test_list_ops.nim new file mode 100644 index 00000000..e69de29b From cf1d2ae301955e6a8aeea9c67b0b1de98850500f Mon Sep 17 00:00:00 2001 From: Norbiox <norbertchmiel.it@gmail.com> Date: Thu, 25 Jan 2024 21:42:37 +0100 Subject: [PATCH 02/24] add tests file scaffold --- exercises/practice/list-ops/test_list_ops.nim | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/exercises/practice/list-ops/test_list_ops.nim b/exercises/practice/list-ops/test_list_ops.nim index e69de29b..d50838db 100644 --- a/exercises/practice/list-ops/test_list_ops.nim +++ b/exercises/practice/list-ops/test_list_ops.nim @@ -0,0 +1,103 @@ +import unittest +import list_ops + + +suite "append entries to a list and return the new list": + test "empty lists": # 485b9452-bf94-40f7-a3db-c3cf4850066a + discard + + test "list to empty list": # 2c894696-b609-4569-b149-8672134d340a + discard + + test "empty list to list": # e842efed-3bf6-4295-b371-4d67a4fdf19c + discard + + test "non-empty lists": # 71dcf5eb-73ae-4a0e-b744-a52ee387922f + discard + + +suite "concatenate a list of lists": + test "empty list": # 28444355-201b-4af2-a2f6-5550227bde21 + discard + + test "list of lists": # 331451c1-9573-42a1-9869-2d06e3b389a9 + discard + + test "list of nested lists": # d6ecd72c-197f-40c3-89a4-aa1f45827e09 + discard + + +suite "filter list returning only values that satisfy the filter function": + test "empty list": # 0524fba8-3e0f-4531-ad2b-f7a43da86a16 + discard + + test "non-empty list": # 88494bd5-f520-4edb-8631-88e415b62d24 + discard + + +suite "returns the length of a list": + test "empty list": # 1cf0b92d-8d96-41d5-9c21-7b3c37cb6aad + discard + + test "non-empty list": # d7b8d2d9-2d16-44c4-9a19-6e5f237cb71e + discard + + +suite "return a list of elements whose values equal the list value transformed by the mapping function": + test "empty list": # c0bc8962-30e2-4bec-9ae4-668b8ecd75aa + discard + + test "non-empty list": # 11e71a95-e78b-4909-b8e4-60cdcaec0e91 + discard + + +suite "folds (reduces) the given list from the left with a function": + test "empty list": # 613b20b7-1873-4070-a3a6-70ae5f50d7cc + discard + + test "direction independent function applied to non-empty list": # e56df3eb-9405-416a-b13a-aabb4c3b5194 + discard + + test "direction dependent function applied to non-empty list": # d2cf5644-aee1-4dfc-9b88-06896676fe27 + discard + + test "empty list": # 36549237-f765-4a4c-bfd9-5d3a8f7b07d2 + discard + + test "direction independent function applied to non-empty list": # 7a626a3c-03ec-42bc-9840-53f280e13067 + discard + + test "direction dependent function applied to non-empty list": # d7fcad99-e88e-40e1-a539-4c519681f390 + discard + + +suite "folds (reduces) the given list from the right with a function": + test "empty list": # aeb576b9-118e-4a57-a451-db49fac20fdc + discard + + test "direction independent function applied to non-empty list": # c4b64e58-313e-4c47-9c68-7764964efb8e + discard + + test "direction dependent function applied to non-empty list": # be396a53-c074-4db3-8dd6-f7ed003cce7c + discard + + test "empty list": # 17214edb-20ba-42fc-bda8-000a5ab525b0 + discard + + test "direction independent function applied to non-empty list": # e1c64db7-9253-4a3d-a7c4-5273b9e2a1bd + discard + + test "direction dependent function applied to non-empty list": # 8066003b-f2ff-437e-9103-66e6df474844 + discard + + +suite "reverse the elements of the list": + test "empty list": # 94231515-050e-4841-943d-d4488ab4ee30 + discard + + test "non-empty list": # fcc03d1e-42e0-4712-b689-d54ad761f360 + discard + + test "list of lists is not flattened": # 40872990-b5b8-4cb8-9085-d91fc0d05d26 + discard + From 43ee62a1c6e653a1b9cff2ecfef31d12a888205b Mon Sep 17 00:00:00 2001 From: Norbiox <norbertchmiel.it@gmail.com> Date: Sat, 27 Jan 2024 11:50:13 +0100 Subject: [PATCH 03/24] add tests and example solutions --- exercises/practice/list-ops/.meta/example.nim | 44 +++++++++++ exercises/practice/list-ops/.meta/tests.toml | 8 +- exercises/practice/list-ops/list_ops.nim | 23 ++++++ exercises/practice/list-ops/test_list_ops.nim | 76 +++++++++++-------- 4 files changed, 117 insertions(+), 34 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index e69de29b..c817b154 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -0,0 +1,44 @@ +proc append*(list1, list2: seq[int]): seq[int] = + if list2.len == 0: + return list1 + return append(list1 & list2[0], list2[1..^1]) + +proc concatenate*(lists: seq[seq[int]]): seq[int] = + var newList = newSeq[int]() + for list in lists: + newList = append(newList, list) + return newList + +proc filter*(predicate: proc(x: int): bool, list: seq[int]): seq[int] = + var newList = newSeq[int]() + for x in list: + if predicate(x): + newList.add(x) + return newList + +proc length*(list: seq[int]): int = + var len = 0 + for _ in list: + len += 1 + return len + +proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = + var newList = newSeq[int]() + for x in list: + newList.add(function(x)) + return newList + +proc foldl*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = + if list.len == 0: + return accumulator + return foldl(function, list[1..^1], function(accumulator, list[0])) + +proc foldr*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = + if list.len == 0: + return accumulator + return function(foldr(function, list[1..^1], accumulator), list[0]) + +proc reverse*(list: seq[int]): seq[int] = + var newList = newSeq[int]() + for x in list: newList.insert(x, 0) + return newList diff --git a/exercises/practice/list-ops/.meta/tests.toml b/exercises/practice/list-ops/.meta/tests.toml index 08b1edc0..16a0fca6 100644 --- a/exercises/practice/list-ops/.meta/tests.toml +++ b/exercises/practice/list-ops/.meta/tests.toml @@ -27,8 +27,8 @@ description = "concatenate a list of lists -> empty list" [331451c1-9573-42a1-9869-2d06e3b389a9] description = "concatenate a list of lists -> list of lists" -[d6ecd72c-197f-40c3-89a4-aa1f45827e09] -description = "concatenate a list of lists -> list of nested lists" +# [d6ecd72c-197f-40c3-89a4-aa1f45827e09] +# description = "concatenate a list of lists -> list of nested lists" [0524fba8-3e0f-4531-ad2b-f7a43da86a16] description = "filter list returning only values that satisfy the filter function -> empty list" @@ -102,5 +102,5 @@ description = "reverse the elements of the list -> empty list" [fcc03d1e-42e0-4712-b689-d54ad761f360] description = "reverse the elements of the list -> non-empty list" -[40872990-b5b8-4cb8-9085-d91fc0d05d26] -description = "reverse the elements of the list -> list of lists is not flattened" +# [40872990-b5b8-4cb8-9085-d91fc0d05d26] +# description = "reverse the elements of the list -> list of lists is not flattened" diff --git a/exercises/practice/list-ops/list_ops.nim b/exercises/practice/list-ops/list_ops.nim index e69de29b..34c75a86 100644 --- a/exercises/practice/list-ops/list_ops.nim +++ b/exercises/practice/list-ops/list_ops.nim @@ -0,0 +1,23 @@ +proc append*(list1, list2: seq[int]): seq[int] = + discard + +proc concatenate*(lists: seq[seq[int]]): seq[int] = + discard + +proc filter*(predicate: proc(x: int): bool, list: seq[int]): seq[int] = + discard + +proc length*(list: seq[int]): int = + discard + +proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = + discard + +proc foldl*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = + discard + +proc foldr*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = + discard + +proc reverse*(list: seq[int]): seq[int] = + discard diff --git a/exercises/practice/list-ops/test_list_ops.nim b/exercises/practice/list-ops/test_list_ops.nim index d50838db..9a4416f9 100644 --- a/exercises/practice/list-ops/test_list_ops.nim +++ b/exercises/practice/list-ops/test_list_ops.nim @@ -4,100 +4,116 @@ import list_ops suite "append entries to a list and return the new list": test "empty lists": # 485b9452-bf94-40f7-a3db-c3cf4850066a - discard + check append(@[], @[]) == newSeq[int]() test "list to empty list": # 2c894696-b609-4569-b149-8672134d340a - discard + check append(@[], @[1, 2, 3, 4]) == @[1, 2, 3, 4] test "empty list to list": # e842efed-3bf6-4295-b371-4d67a4fdf19c - discard + check append(@[1, 2, 3, 4], @[]) == @[1, 2, 3, 4] test "non-empty lists": # 71dcf5eb-73ae-4a0e-b744-a52ee387922f - discard + check append(@[1, 2], @[2, 3, 4, 5]) == @[1, 2, 2, 3, 4, 5] suite "concatenate a list of lists": test "empty list": # 28444355-201b-4af2-a2f6-5550227bde21 - discard + check concatenate(@[]) == newSeq[int]() test "list of lists": # 331451c1-9573-42a1-9869-2d06e3b389a9 - discard + check concatenate(@[@[1, 2], @[3], @[], @[4, 5, 6]]) == @[1, 2, 3, 4, 5, 6] - test "list of nested lists": # d6ecd72c-197f-40c3-89a4-aa1f45827e09 - discard + # test "list of nested lists": # d6ecd72c-197f-40c3-89a4-aa1f45827e09 + # check concatenate(@[@[@[1], @[2]], @[@[3]], @[@[]], @[@[4, 5, 6]]]) == @[@[1], @[2], @[3], @[], @[4, 5, 6]] suite "filter list returning only values that satisfy the filter function": + func predicate(x: int): bool = x mod 2 == 1 + test "empty list": # 0524fba8-3e0f-4531-ad2b-f7a43da86a16 - discard + check filter(predicate, @[]) == newSeq[int]() test "non-empty list": # 88494bd5-f520-4edb-8631-88e415b62d24 - discard + check filter(predicate, @[1, 2, 3, 5]) == @[1, 3, 5] suite "returns the length of a list": test "empty list": # 1cf0b92d-8d96-41d5-9c21-7b3c37cb6aad - discard + check length(@[]) == 0 test "non-empty list": # d7b8d2d9-2d16-44c4-9a19-6e5f237cb71e - discard + check length(@[1, 2, 3, 4]) == 4 suite "return a list of elements whose values equal the list value transformed by the mapping function": + func function(x: int): int = x + 1 + test "empty list": # c0bc8962-30e2-4bec-9ae4-668b8ecd75aa - discard + check map(function, @[]) == newSeq[int]() test "non-empty list": # 11e71a95-e78b-4909-b8e4-60cdcaec0e91 - discard + check map(function, @[1, 3, 5, 7]) == @[2, 4, 6, 8] suite "folds (reduces) the given list from the left with a function": test "empty list": # 613b20b7-1873-4070-a3a6-70ae5f50d7cc - discard + func function(x: int, y: int): int = x + y + check foldl(function, @[], 2) == 2 test "direction independent function applied to non-empty list": # e56df3eb-9405-416a-b13a-aabb4c3b5194 - discard + func function(x: int, y: int): int = x + y + check foldl(function, @[1, 2, 3, 4], 5) == 15 test "direction dependent function applied to non-empty list": # d2cf5644-aee1-4dfc-9b88-06896676fe27 - discard + func function(x: int, y: int): int | float = x - y + check foldl(function, @[1, 2, 3, 4], 24) == 14 test "empty list": # 36549237-f765-4a4c-bfd9-5d3a8f7b07d2 - discard + func function(x: int, y: int): int = y + x + check foldl(function, @[], 2) == 2 test "direction independent function applied to non-empty list": # 7a626a3c-03ec-42bc-9840-53f280e13067 - discard + func function(x: int, y: int): int = y + x + check foldl(function, @[1, 2, 3, 4], 5) == 15 test "direction dependent function applied to non-empty list": # d7fcad99-e88e-40e1-a539-4c519681f390 - discard + func function(x: int, y: int): int = y - x + check foldl(function, @[1, 2, 3, 4], 5) == 7 suite "folds (reduces) the given list from the right with a function": test "empty list": # aeb576b9-118e-4a57-a451-db49fac20fdc - discard + func function(x: int, y: int): int = x + y + check foldr(function, @[], 2) == 2 test "direction independent function applied to non-empty list": # c4b64e58-313e-4c47-9c68-7764964efb8e - discard + func function(x: int, y: int): int = x + y + check foldr(function, @[1, 2, 3, 4], 5) == 15 test "direction dependent function applied to non-empty list": # be396a53-c074-4db3-8dd6-f7ed003cce7c - discard + func function(x: int, y: int): int | float = x - y + check foldr(function, @[1, 2, 3, 4], 24) == 14 test "empty list": # 17214edb-20ba-42fc-bda8-000a5ab525b0 - discard + func function(x: int, y: int): int = y + x + check foldr(function, @[], 2) == 2 test "direction independent function applied to non-empty list": # e1c64db7-9253-4a3d-a7c4-5273b9e2a1bd - discard + func function(x: int, y: int): int = y + x + check foldr(function, @[1, 2, 3, 4], 5) == 15 test "direction dependent function applied to non-empty list": # 8066003b-f2ff-437e-9103-66e6df474844 - discard + func function(x: int, y: int): int = y - x + check foldr(function, @[1, 2, 3, 4], 5) == 3 suite "reverse the elements of the list": test "empty list": # 94231515-050e-4841-943d-d4488ab4ee30 - discard + check reverse(@[]) == newSeq[int]() test "non-empty list": # fcc03d1e-42e0-4712-b689-d54ad761f360 - discard + check reverse(@[1, 2, 3, 4]) == @[4, 3, 2, 1] - test "list of lists is not flattened": # 40872990-b5b8-4cb8-9085-d91fc0d05d26 - discard + # test "list of lists is not flattened": # 40872990-b5b8-4cb8-9085-d91fc0d05d26 + # check reverse(@[@[], @[1], @[2, 3]]) == @[@[2, 3], @[1], @[]] From 8fbe2938e0a46055f23971d9d557b89fd3ba529c Mon Sep 17 00:00:00 2001 From: Norbiox <norbertchmiel.it@gmail.com> Date: Sat, 27 Jan 2024 11:52:00 +0100 Subject: [PATCH 04/24] change difficulty and move higher in config --- config.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config.json b/config.json index 381d84fd..0447fdab 100644 --- a/config.json +++ b/config.json @@ -953,6 +953,14 @@ "integers" ] }, + { + "slug": "list-ops", + "name": "List Ops", + "uuid": "779343ba-9b40-4d43-b696-2267c4eecde0", + "practices": [], + "prerequisites": [], + "difficulty": 3 + }, { "slug": "linked-list", "name": "Linked List", @@ -979,14 +987,6 @@ "events", "reactive_programming" ] - }, - { - "slug": "list-ops", - "name": "List Ops", - "uuid": "779343ba-9b40-4d43-b696-2267c4eecde0", - "practices": [], - "prerequisites": [], - "difficulty": 1 } ] }, From ddc71e69b778bcd8dfbb4990c1c2eebd3cf94011 Mon Sep 17 00:00:00 2001 From: Norbiox <norbertchmiel.it@gmail.com> Date: Sat, 27 Jan 2024 12:15:18 +0100 Subject: [PATCH 05/24] remove trailing newlines --- exercises/practice/list-ops/test_list_ops.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/exercises/practice/list-ops/test_list_ops.nim b/exercises/practice/list-ops/test_list_ops.nim index 9a4416f9..8a5fa46a 100644 --- a/exercises/practice/list-ops/test_list_ops.nim +++ b/exercises/practice/list-ops/test_list_ops.nim @@ -116,4 +116,3 @@ suite "reverse the elements of the list": # test "list of lists is not flattened": # 40872990-b5b8-4cb8-9085-d91fc0d05d26 # check reverse(@[@[], @[1], @[2, 3]]) == @[@[2, 3], @[1], @[]] - From 31a2f5c572cd0cc9c9f4f414172d8d8511ee9473 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:01 +0100 Subject: [PATCH 06/24] exercises(list-ops): example: refactor `length` --- exercises/practice/list-ops/.meta/example.nim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index c817b154..77293c5e 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -17,10 +17,9 @@ proc filter*(predicate: proc(x: int): bool, list: seq[int]): seq[int] = return newList proc length*(list: seq[int]): int = - var len = 0 + result = 0 for _ in list: - len += 1 - return len + inc result proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = var newList = newSeq[int]() From 03e10f36644f98ce7e506488c1c629669725975c Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:02 +0100 Subject: [PATCH 07/24] exercises(list-ops): example: refactor `length` further The `append`, `foldl`, and `foldr` procs each use `len`, so there's no real benefit to pretending it doesn't exist in the `length` proc. An alternative would be for this exercise to use some `distinct seq`, but that's probably not worthwhile. --- exercises/practice/list-ops/.meta/example.nim | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index 77293c5e..a919fd02 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -17,9 +17,7 @@ proc filter*(predicate: proc(x: int): bool, list: seq[int]): seq[int] = return newList proc length*(list: seq[int]): int = - result = 0 - for _ in list: - inc result + list.len proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = var newList = newSeq[int]() From 26b4b6ed973439468b299f4b71b39d44a6fbf121 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:03 +0100 Subject: [PATCH 08/24] exercises(list-ops): example: use result, not newList --- exercises/practice/list-ops/.meta/example.nim | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index a919fd02..c06e3ccc 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -4,26 +4,23 @@ proc append*(list1, list2: seq[int]): seq[int] = return append(list1 & list2[0], list2[1..^1]) proc concatenate*(lists: seq[seq[int]]): seq[int] = - var newList = newSeq[int]() + result = @[] for list in lists: - newList = append(newList, list) - return newList + result = append(result, list) proc filter*(predicate: proc(x: int): bool, list: seq[int]): seq[int] = - var newList = newSeq[int]() + result = @[] for x in list: if predicate(x): - newList.add(x) - return newList + result.add(x) proc length*(list: seq[int]): int = list.len proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = - var newList = newSeq[int]() + result = @[] for x in list: - newList.add(function(x)) - return newList + result.add(function(x)) proc foldl*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = if list.len == 0: @@ -36,6 +33,5 @@ proc foldr*(function: proc(x, y: int): int, list: seq[int], accumulator: int): i return function(foldr(function, list[1..^1], accumulator), list[0]) proc reverse*(list: seq[int]): seq[int] = - var newList = newSeq[int]() - for x in list: newList.insert(x, 0) - return newList + result = @[] + for x in list: result.insert(x, 0) From c5ffbc367c935884834a08e61772669625aaf631 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:04 +0100 Subject: [PATCH 09/24] exercises(list-ops): example: format loop consistently --- exercises/practice/list-ops/.meta/example.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index c06e3ccc..f84d53fd 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -34,4 +34,5 @@ proc foldr*(function: proc(x, y: int): int, list: seq[int], accumulator: int): i proc reverse*(list: seq[int]): seq[int] = result = @[] - for x in list: result.insert(x, 0) + for x in list: + result.insert(x, 0) From aa462b618b3255ea378b6274a0ea373808e239c4 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:05 +0100 Subject: [PATCH 10/24] exercises(list-ops): example: refactor `reverse` --- exercises/practice/list-ops/.meta/example.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index f84d53fd..bc66cb8d 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -33,6 +33,6 @@ proc foldr*(function: proc(x, y: int): int, list: seq[int], accumulator: int): i return function(foldr(function, list[1..^1], accumulator), list[0]) proc reverse*(list: seq[int]): seq[int] = - result = @[] - for x in list: - result.insert(x, 0) + result = newSeq[int](list.len) + for i, x in list: + result[list.high - i] = x From 4a3cd6c997d5f4050817b8ee5c5b48ff6a03d73a Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:06 +0100 Subject: [PATCH 11/24] exercises(list-ops): example: remove parens for `add` --- exercises/practice/list-ops/.meta/example.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index bc66cb8d..c6e91a0d 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -12,7 +12,7 @@ proc filter*(predicate: proc(x: int): bool, list: seq[int]): seq[int] = result = @[] for x in list: if predicate(x): - result.add(x) + result.add x proc length*(list: seq[int]): int = list.len @@ -20,7 +20,7 @@ proc length*(list: seq[int]): int = proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = result = @[] for x in list: - result.add(function(x)) + result.add function(x) proc foldl*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = if list.len == 0: From 7c3c54f6c20f8b3dbdf4bc819c7c348bf8d61c0e Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:07 +0100 Subject: [PATCH 12/24] exercises(list-ops): example: refactor `map` --- exercises/practice/list-ops/.meta/example.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index c6e91a0d..e09c8282 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -18,9 +18,9 @@ proc length*(list: seq[int]): int = list.len proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = - result = @[] - for x in list: - result.add function(x) + result = newSeq[int](list.len) + for i, x in list: + result[i] = function(x) proc foldl*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = if list.len == 0: From d43eea4d53132a3c22b19a6cf47f947616f27237 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:08 +0100 Subject: [PATCH 13/24] exercises(list-ops): example: avoid `return` --- exercises/practice/list-ops/.meta/example.nim | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index e09c8282..e2267050 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -1,7 +1,8 @@ proc append*(list1, list2: seq[int]): seq[int] = if list2.len == 0: - return list1 - return append(list1 & list2[0], list2[1..^1]) + list1 + else: + append(list1 & list2[0], list2[1..^1]) proc concatenate*(lists: seq[seq[int]]): seq[int] = result = @[] @@ -24,13 +25,15 @@ proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = proc foldl*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = if list.len == 0: - return accumulator - return foldl(function, list[1..^1], function(accumulator, list[0])) + accumulator + else: + foldl(function, list[1..^1], function(accumulator, list[0])) proc foldr*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = if list.len == 0: - return accumulator - return function(foldr(function, list[1..^1], accumulator), list[0]) + accumulator + else: + function(foldr(function, list[1..^1], accumulator), list[0]) proc reverse*(list: seq[int]): seq[int] = result = newSeq[int](list.len) From eedf26cecac8050618046d0ea9f1d306eaab7b6a Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:09 +0100 Subject: [PATCH 14/24] exercises(list-ops): example: use `func` --- exercises/practice/list-ops/.meta/example.nim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index e2267050..c3e33fd5 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -1,41 +1,41 @@ -proc append*(list1, list2: seq[int]): seq[int] = +func append*(list1, list2: seq[int]): seq[int] = if list2.len == 0: list1 else: append(list1 & list2[0], list2[1..^1]) -proc concatenate*(lists: seq[seq[int]]): seq[int] = +func concatenate*(lists: seq[seq[int]]): seq[int] = result = @[] for list in lists: result = append(result, list) -proc filter*(predicate: proc(x: int): bool, list: seq[int]): seq[int] = +func filter*(predicate: proc(x: int): bool {.noSideEffect.}, list: seq[int]): seq[int] = result = @[] for x in list: if predicate(x): result.add x -proc length*(list: seq[int]): int = +func length*(list: seq[int]): int = list.len -proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = +func map*(function: proc(x: int): int {.noSideEffect.}, list: seq[int]): seq[int] = result = newSeq[int](list.len) for i, x in list: result[i] = function(x) -proc foldl*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = +func foldl*(function: proc(x, y: int): int {.noSideEffect.}, list: seq[int], accumulator: int): int = if list.len == 0: accumulator else: foldl(function, list[1..^1], function(accumulator, list[0])) -proc foldr*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = +func foldr*(function: proc(x, y: int): int {.noSideEffect.}, list: seq[int], accumulator: int): int = if list.len == 0: accumulator else: function(foldr(function, list[1..^1], accumulator), list[0]) -proc reverse*(list: seq[int]): seq[int] = +func reverse*(list: seq[int]): seq[int] = result = newSeq[int](list.len) for i, x in list: result[list.high - i] = x From d628b5bdd3e86c1b3fa45d0fd050311a9539d652 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:10 +0100 Subject: [PATCH 15/24] exercises(list-ops): example: wrap (now-)long lines --- exercises/practice/list-ops/.meta/example.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index c3e33fd5..900083e6 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -23,13 +23,15 @@ func map*(function: proc(x: int): int {.noSideEffect.}, list: seq[int]): seq[int for i, x in list: result[i] = function(x) -func foldl*(function: proc(x, y: int): int {.noSideEffect.}, list: seq[int], accumulator: int): int = +func foldl*(function: proc(x, y: int): int {.noSideEffect.}, list: seq[int], + accumulator: int): int = if list.len == 0: accumulator else: foldl(function, list[1..^1], function(accumulator, list[0])) -func foldr*(function: proc(x, y: int): int {.noSideEffect.}, list: seq[int], accumulator: int): int = +func foldr*(function: proc(x, y: int): int {.noSideEffect.}, list: seq[int], + accumulator: int): int = if list.len == 0: accumulator else: From ae8ae1b5dfb97f225daca767469844e56f219ec8 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:11 +0100 Subject: [PATCH 16/24] exercises(list-ops): example: refactor `append` --- exercises/practice/list-ops/.meta/example.nim | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index 900083e6..5541c483 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -1,8 +1,14 @@ func append*(list1, list2: seq[int]): seq[int] = if list2.len == 0: - list1 - else: - append(list1 & list2[0], list2[1..^1]) + return list1 + result = newSeq[int](list1.len + list2.len) + var i = 0 + for x in list1: + result[i] = x + inc i + for x in list2: + result[i] = x + inc i func concatenate*(lists: seq[seq[int]]): seq[int] = result = @[] From aa8f0366f66a3721b0512ffc663c61350fe31fe3 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:12 +0100 Subject: [PATCH 17/24] exercises(list-ops): tests: prefer to check len == 0 --- exercises/practice/list-ops/test_list_ops.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/exercises/practice/list-ops/test_list_ops.nim b/exercises/practice/list-ops/test_list_ops.nim index 8a5fa46a..93060d9d 100644 --- a/exercises/practice/list-ops/test_list_ops.nim +++ b/exercises/practice/list-ops/test_list_ops.nim @@ -4,7 +4,7 @@ import list_ops suite "append entries to a list and return the new list": test "empty lists": # 485b9452-bf94-40f7-a3db-c3cf4850066a - check append(@[], @[]) == newSeq[int]() + check append(@[], @[]).len == 0 test "list to empty list": # 2c894696-b609-4569-b149-8672134d340a check append(@[], @[1, 2, 3, 4]) == @[1, 2, 3, 4] @@ -18,7 +18,7 @@ suite "append entries to a list and return the new list": suite "concatenate a list of lists": test "empty list": # 28444355-201b-4af2-a2f6-5550227bde21 - check concatenate(@[]) == newSeq[int]() + check concatenate(@[]).len == 0 test "list of lists": # 331451c1-9573-42a1-9869-2d06e3b389a9 check concatenate(@[@[1, 2], @[3], @[], @[4, 5, 6]]) == @[1, 2, 3, 4, 5, 6] @@ -31,7 +31,7 @@ suite "filter list returning only values that satisfy the filter function": func predicate(x: int): bool = x mod 2 == 1 test "empty list": # 0524fba8-3e0f-4531-ad2b-f7a43da86a16 - check filter(predicate, @[]) == newSeq[int]() + check filter(predicate, @[]).len == 0 test "non-empty list": # 88494bd5-f520-4edb-8631-88e415b62d24 check filter(predicate, @[1, 2, 3, 5]) == @[1, 3, 5] @@ -49,7 +49,7 @@ suite "return a list of elements whose values equal the list value transformed b func function(x: int): int = x + 1 test "empty list": # c0bc8962-30e2-4bec-9ae4-668b8ecd75aa - check map(function, @[]) == newSeq[int]() + check map(function, @[]).len == 0 test "non-empty list": # 11e71a95-e78b-4909-b8e4-60cdcaec0e91 check map(function, @[1, 3, 5, 7]) == @[2, 4, 6, 8] @@ -109,7 +109,7 @@ suite "folds (reduces) the given list from the right with a function": suite "reverse the elements of the list": test "empty list": # 94231515-050e-4841-943d-d4488ab4ee30 - check reverse(@[]) == newSeq[int]() + check reverse(@[]).len == 0 test "non-empty list": # fcc03d1e-42e0-4712-b689-d54ad761f360 check reverse(@[1, 2, 3, 4]) == @[4, 3, 2, 1] From 54aa4e70dc7159dff6833c99973c82cded4e4c6a Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:13 +0100 Subject: [PATCH 18/24] exercises(list-ops): example: prefer openArray --- exercises/practice/list-ops/.meta/example.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index 5541c483..5962faae 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -10,40 +10,40 @@ func append*(list1, list2: seq[int]): seq[int] = result[i] = x inc i -func concatenate*(lists: seq[seq[int]]): seq[int] = +func concatenate*(lists: openArray[seq[int]]): seq[int] = result = @[] for list in lists: result = append(result, list) -func filter*(predicate: proc(x: int): bool {.noSideEffect.}, list: seq[int]): seq[int] = +func filter*(predicate: proc(x: int): bool {.noSideEffect.}, list: openArray[int]): seq[int] = result = @[] for x in list: if predicate(x): result.add x -func length*(list: seq[int]): int = +func length*(list: openArray[int]): int = list.len -func map*(function: proc(x: int): int {.noSideEffect.}, list: seq[int]): seq[int] = +func map*(function: proc(x: int): int {.noSideEffect.}, list: openArray[int]): seq[int] = result = newSeq[int](list.len) for i, x in list: result[i] = function(x) -func foldl*(function: proc(x, y: int): int {.noSideEffect.}, list: seq[int], +func foldl*(function: proc(x, y: int): int {.noSideEffect.}, list: openArray[int], accumulator: int): int = if list.len == 0: accumulator else: foldl(function, list[1..^1], function(accumulator, list[0])) -func foldr*(function: proc(x, y: int): int {.noSideEffect.}, list: seq[int], +func foldr*(function: proc(x, y: int): int {.noSideEffect.}, list: openArray[int], accumulator: int): int = if list.len == 0: accumulator else: function(foldr(function, list[1..^1], accumulator), list[0]) -func reverse*(list: seq[int]): seq[int] = +func reverse*(list: openArray[int]): seq[int] = result = newSeq[int](list.len) for i, x in list: result[list.high - i] = x From cea855e707fec256aff4e99a8f9ffb6184420684 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:14 +0100 Subject: [PATCH 19/24] exercises(list-ops): example, stub, test: write `list` first Support the method call syntax [1]. [1] https://nim-lang.org/docs/manual.html#procedures-method-call-syntax --- exercises/practice/list-ops/.meta/example.nim | 12 +++---- exercises/practice/list-ops/list_ops.nim | 8 ++--- exercises/practice/list-ops/test_list_ops.nim | 32 +++++++++---------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index 5962faae..e29b45fe 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -15,7 +15,7 @@ func concatenate*(lists: openArray[seq[int]]): seq[int] = for list in lists: result = append(result, list) -func filter*(predicate: proc(x: int): bool {.noSideEffect.}, list: openArray[int]): seq[int] = +func filter*(list: openArray[int], predicate: proc(x: int): bool {.noSideEffect.}): seq[int] = result = @[] for x in list: if predicate(x): @@ -24,24 +24,24 @@ func filter*(predicate: proc(x: int): bool {.noSideEffect.}, list: openArray[int func length*(list: openArray[int]): int = list.len -func map*(function: proc(x: int): int {.noSideEffect.}, list: openArray[int]): seq[int] = +func map*(list: openArray[int], function: proc(x: int): int {.noSideEffect.}): seq[int] = result = newSeq[int](list.len) for i, x in list: result[i] = function(x) -func foldl*(function: proc(x, y: int): int {.noSideEffect.}, list: openArray[int], +func foldl*(list: openArray[int], function: proc(x, y: int): int {.noSideEffect.}, accumulator: int): int = if list.len == 0: accumulator else: - foldl(function, list[1..^1], function(accumulator, list[0])) + foldl(list[1..^1], function, function(accumulator, list[0])) -func foldr*(function: proc(x, y: int): int {.noSideEffect.}, list: openArray[int], +func foldr*(list: openArray[int], function: proc(x, y: int): int {.noSideEffect.}, accumulator: int): int = if list.len == 0: accumulator else: - function(foldr(function, list[1..^1], accumulator), list[0]) + function(foldr(list[1..^1], function, accumulator), list[0]) func reverse*(list: openArray[int]): seq[int] = result = newSeq[int](list.len) diff --git a/exercises/practice/list-ops/list_ops.nim b/exercises/practice/list-ops/list_ops.nim index 34c75a86..459ecaf8 100644 --- a/exercises/practice/list-ops/list_ops.nim +++ b/exercises/practice/list-ops/list_ops.nim @@ -4,19 +4,19 @@ proc append*(list1, list2: seq[int]): seq[int] = proc concatenate*(lists: seq[seq[int]]): seq[int] = discard -proc filter*(predicate: proc(x: int): bool, list: seq[int]): seq[int] = +proc filter*(list: seq[int], predicate: proc(x: int): bool): seq[int] = discard proc length*(list: seq[int]): int = discard -proc map*(function: proc(x: int): int, list: seq[int]): seq[int] = +proc map*(list: seq[int], function: proc(x: int): int): seq[int] = discard -proc foldl*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = +proc foldl*(list: seq[int], function: proc(x, y: int): int, accumulator: int): int = discard -proc foldr*(function: proc(x, y: int): int, list: seq[int], accumulator: int): int = +proc foldr*(list: seq[int], function: proc(x, y: int): int, accumulator: int): int = discard proc reverse*(list: seq[int]): seq[int] = diff --git a/exercises/practice/list-ops/test_list_ops.nim b/exercises/practice/list-ops/test_list_ops.nim index 93060d9d..7eae7f6d 100644 --- a/exercises/practice/list-ops/test_list_ops.nim +++ b/exercises/practice/list-ops/test_list_ops.nim @@ -31,10 +31,10 @@ suite "filter list returning only values that satisfy the filter function": func predicate(x: int): bool = x mod 2 == 1 test "empty list": # 0524fba8-3e0f-4531-ad2b-f7a43da86a16 - check filter(predicate, @[]).len == 0 + check filter(@[], predicate).len == 0 test "non-empty list": # 88494bd5-f520-4edb-8631-88e415b62d24 - check filter(predicate, @[1, 2, 3, 5]) == @[1, 3, 5] + check filter(@[1, 2, 3, 5], predicate) == @[1, 3, 5] suite "returns the length of a list": @@ -49,62 +49,62 @@ suite "return a list of elements whose values equal the list value transformed b func function(x: int): int = x + 1 test "empty list": # c0bc8962-30e2-4bec-9ae4-668b8ecd75aa - check map(function, @[]).len == 0 + check map(@[], function).len == 0 test "non-empty list": # 11e71a95-e78b-4909-b8e4-60cdcaec0e91 - check map(function, @[1, 3, 5, 7]) == @[2, 4, 6, 8] + check map(@[1, 3, 5, 7], function) == @[2, 4, 6, 8] suite "folds (reduces) the given list from the left with a function": test "empty list": # 613b20b7-1873-4070-a3a6-70ae5f50d7cc func function(x: int, y: int): int = x + y - check foldl(function, @[], 2) == 2 + check foldl(@[], function, 2) == 2 test "direction independent function applied to non-empty list": # e56df3eb-9405-416a-b13a-aabb4c3b5194 func function(x: int, y: int): int = x + y - check foldl(function, @[1, 2, 3, 4], 5) == 15 + check foldl(@[1, 2, 3, 4], function, 5) == 15 test "direction dependent function applied to non-empty list": # d2cf5644-aee1-4dfc-9b88-06896676fe27 func function(x: int, y: int): int | float = x - y - check foldl(function, @[1, 2, 3, 4], 24) == 14 + check foldl(@[1, 2, 3, 4], function, 24) == 14 test "empty list": # 36549237-f765-4a4c-bfd9-5d3a8f7b07d2 func function(x: int, y: int): int = y + x - check foldl(function, @[], 2) == 2 + check foldl(@[], function, 2) == 2 test "direction independent function applied to non-empty list": # 7a626a3c-03ec-42bc-9840-53f280e13067 func function(x: int, y: int): int = y + x - check foldl(function, @[1, 2, 3, 4], 5) == 15 + check foldl(@[1, 2, 3, 4], function, 5) == 15 test "direction dependent function applied to non-empty list": # d7fcad99-e88e-40e1-a539-4c519681f390 func function(x: int, y: int): int = y - x - check foldl(function, @[1, 2, 3, 4], 5) == 7 + check foldl(@[1, 2, 3, 4], function, 5) == 7 suite "folds (reduces) the given list from the right with a function": test "empty list": # aeb576b9-118e-4a57-a451-db49fac20fdc func function(x: int, y: int): int = x + y - check foldr(function, @[], 2) == 2 + check foldr(@[], function, 2) == 2 test "direction independent function applied to non-empty list": # c4b64e58-313e-4c47-9c68-7764964efb8e func function(x: int, y: int): int = x + y - check foldr(function, @[1, 2, 3, 4], 5) == 15 + check foldr(@[1, 2, 3, 4], function, 5) == 15 test "direction dependent function applied to non-empty list": # be396a53-c074-4db3-8dd6-f7ed003cce7c func function(x: int, y: int): int | float = x - y - check foldr(function, @[1, 2, 3, 4], 24) == 14 + check foldr(@[1, 2, 3, 4], function, 24) == 14 test "empty list": # 17214edb-20ba-42fc-bda8-000a5ab525b0 func function(x: int, y: int): int = y + x - check foldr(function, @[], 2) == 2 + check foldr(@[], function, 2) == 2 test "direction independent function applied to non-empty list": # e1c64db7-9253-4a3d-a7c4-5273b9e2a1bd func function(x: int, y: int): int = y + x - check foldr(function, @[1, 2, 3, 4], 5) == 15 + check foldr(@[1, 2, 3, 4], function, 5) == 15 test "direction dependent function applied to non-empty list": # 8066003b-f2ff-437e-9103-66e6df474844 func function(x: int, y: int): int = y - x - check foldr(function, @[1, 2, 3, 4], 5) == 3 + check foldr(@[1, 2, 3, 4], function, 5) == 3 suite "reverse the elements of the list": From 42896c8d9dcd27645126fc074e9218211273f69b Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:15 +0100 Subject: [PATCH 20/24] exercises(list-ops): tests: remove unimplemented test cases --- exercises/practice/list-ops/test_list_ops.nim | 6 ------ 1 file changed, 6 deletions(-) diff --git a/exercises/practice/list-ops/test_list_ops.nim b/exercises/practice/list-ops/test_list_ops.nim index 7eae7f6d..e03e7147 100644 --- a/exercises/practice/list-ops/test_list_ops.nim +++ b/exercises/practice/list-ops/test_list_ops.nim @@ -23,9 +23,6 @@ suite "concatenate a list of lists": test "list of lists": # 331451c1-9573-42a1-9869-2d06e3b389a9 check concatenate(@[@[1, 2], @[3], @[], @[4, 5, 6]]) == @[1, 2, 3, 4, 5, 6] - # test "list of nested lists": # d6ecd72c-197f-40c3-89a4-aa1f45827e09 - # check concatenate(@[@[@[1], @[2]], @[@[3]], @[@[]], @[@[4, 5, 6]]]) == @[@[1], @[2], @[3], @[], @[4, 5, 6]] - suite "filter list returning only values that satisfy the filter function": func predicate(x: int): bool = x mod 2 == 1 @@ -113,6 +110,3 @@ suite "reverse the elements of the list": test "non-empty list": # fcc03d1e-42e0-4712-b689-d54ad761f360 check reverse(@[1, 2, 3, 4]) == @[4, 3, 2, 1] - - # test "list of lists is not flattened": # 40872990-b5b8-4cb8-9085-d91fc0d05d26 - # check reverse(@[@[], @[1], @[2, 3]]) == @[@[2, 3], @[1], @[]] From f945be9e6d6f33ede4663335b6215ef666d36028 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:16 +0100 Subject: [PATCH 21/24] exercises(list-ops): tests: remove UUID comments --- exercises/practice/list-ops/test_list_ops.nim | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/exercises/practice/list-ops/test_list_ops.nim b/exercises/practice/list-ops/test_list_ops.nim index e03e7147..17fe4416 100644 --- a/exercises/practice/list-ops/test_list_ops.nim +++ b/exercises/practice/list-ops/test_list_ops.nim @@ -3,110 +3,110 @@ import list_ops suite "append entries to a list and return the new list": - test "empty lists": # 485b9452-bf94-40f7-a3db-c3cf4850066a + test "empty lists": check append(@[], @[]).len == 0 - test "list to empty list": # 2c894696-b609-4569-b149-8672134d340a + test "list to empty list": check append(@[], @[1, 2, 3, 4]) == @[1, 2, 3, 4] - test "empty list to list": # e842efed-3bf6-4295-b371-4d67a4fdf19c + test "empty list to list": check append(@[1, 2, 3, 4], @[]) == @[1, 2, 3, 4] - test "non-empty lists": # 71dcf5eb-73ae-4a0e-b744-a52ee387922f + test "non-empty lists": check append(@[1, 2], @[2, 3, 4, 5]) == @[1, 2, 2, 3, 4, 5] suite "concatenate a list of lists": - test "empty list": # 28444355-201b-4af2-a2f6-5550227bde21 + test "empty list": check concatenate(@[]).len == 0 - test "list of lists": # 331451c1-9573-42a1-9869-2d06e3b389a9 + test "list of lists": check concatenate(@[@[1, 2], @[3], @[], @[4, 5, 6]]) == @[1, 2, 3, 4, 5, 6] suite "filter list returning only values that satisfy the filter function": func predicate(x: int): bool = x mod 2 == 1 - test "empty list": # 0524fba8-3e0f-4531-ad2b-f7a43da86a16 + test "empty list": check filter(@[], predicate).len == 0 - test "non-empty list": # 88494bd5-f520-4edb-8631-88e415b62d24 + test "non-empty list": check filter(@[1, 2, 3, 5], predicate) == @[1, 3, 5] suite "returns the length of a list": - test "empty list": # 1cf0b92d-8d96-41d5-9c21-7b3c37cb6aad + test "empty list": check length(@[]) == 0 - test "non-empty list": # d7b8d2d9-2d16-44c4-9a19-6e5f237cb71e + test "non-empty list": check length(@[1, 2, 3, 4]) == 4 suite "return a list of elements whose values equal the list value transformed by the mapping function": func function(x: int): int = x + 1 - test "empty list": # c0bc8962-30e2-4bec-9ae4-668b8ecd75aa + test "empty list": check map(@[], function).len == 0 - test "non-empty list": # 11e71a95-e78b-4909-b8e4-60cdcaec0e91 + test "non-empty list": check map(@[1, 3, 5, 7], function) == @[2, 4, 6, 8] suite "folds (reduces) the given list from the left with a function": - test "empty list": # 613b20b7-1873-4070-a3a6-70ae5f50d7cc + test "empty list": func function(x: int, y: int): int = x + y check foldl(@[], function, 2) == 2 - test "direction independent function applied to non-empty list": # e56df3eb-9405-416a-b13a-aabb4c3b5194 + test "direction independent function applied to non-empty list": func function(x: int, y: int): int = x + y check foldl(@[1, 2, 3, 4], function, 5) == 15 - test "direction dependent function applied to non-empty list": # d2cf5644-aee1-4dfc-9b88-06896676fe27 + test "direction dependent function applied to non-empty list": func function(x: int, y: int): int | float = x - y check foldl(@[1, 2, 3, 4], function, 24) == 14 - test "empty list": # 36549237-f765-4a4c-bfd9-5d3a8f7b07d2 + test "empty list": func function(x: int, y: int): int = y + x check foldl(@[], function, 2) == 2 - test "direction independent function applied to non-empty list": # 7a626a3c-03ec-42bc-9840-53f280e13067 + test "direction independent function applied to non-empty list": func function(x: int, y: int): int = y + x check foldl(@[1, 2, 3, 4], function, 5) == 15 - test "direction dependent function applied to non-empty list": # d7fcad99-e88e-40e1-a539-4c519681f390 + test "direction dependent function applied to non-empty list": func function(x: int, y: int): int = y - x check foldl(@[1, 2, 3, 4], function, 5) == 7 suite "folds (reduces) the given list from the right with a function": - test "empty list": # aeb576b9-118e-4a57-a451-db49fac20fdc + test "empty list": func function(x: int, y: int): int = x + y check foldr(@[], function, 2) == 2 - test "direction independent function applied to non-empty list": # c4b64e58-313e-4c47-9c68-7764964efb8e + test "direction independent function applied to non-empty list": func function(x: int, y: int): int = x + y check foldr(@[1, 2, 3, 4], function, 5) == 15 - test "direction dependent function applied to non-empty list": # be396a53-c074-4db3-8dd6-f7ed003cce7c + test "direction dependent function applied to non-empty list": func function(x: int, y: int): int | float = x - y check foldr(@[1, 2, 3, 4], function, 24) == 14 - test "empty list": # 17214edb-20ba-42fc-bda8-000a5ab525b0 + test "empty list": func function(x: int, y: int): int = y + x check foldr(@[], function, 2) == 2 - test "direction independent function applied to non-empty list": # e1c64db7-9253-4a3d-a7c4-5273b9e2a1bd + test "direction independent function applied to non-empty list": func function(x: int, y: int): int = y + x check foldr(@[1, 2, 3, 4], function, 5) == 15 - test "direction dependent function applied to non-empty list": # 8066003b-f2ff-437e-9103-66e6df474844 + test "direction dependent function applied to non-empty list": func function(x: int, y: int): int = y - x check foldr(@[1, 2, 3, 4], function, 5) == 3 suite "reverse the elements of the list": - test "empty list": # 94231515-050e-4841-943d-d4488ab4ee30 + test "empty list": check reverse(@[]).len == 0 - test "non-empty list": # fcc03d1e-42e0-4712-b689-d54ad761f360 + test "non-empty list": check reverse(@[1, 2, 3, 4]) == @[4, 3, 2, 1] From ecf1542e3f3cc59bf2e51fef96dd4361247e441f Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:17 +0100 Subject: [PATCH 22/24] exercises(list-ops): tests: remove float from return type --- exercises/practice/list-ops/test_list_ops.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/practice/list-ops/test_list_ops.nim b/exercises/practice/list-ops/test_list_ops.nim index 17fe4416..4973ff75 100644 --- a/exercises/practice/list-ops/test_list_ops.nim +++ b/exercises/practice/list-ops/test_list_ops.nim @@ -62,7 +62,7 @@ suite "folds (reduces) the given list from the left with a function": check foldl(@[1, 2, 3, 4], function, 5) == 15 test "direction dependent function applied to non-empty list": - func function(x: int, y: int): int | float = x - y + func function(x: int, y: int): int = x - y check foldl(@[1, 2, 3, 4], function, 24) == 14 test "empty list": @@ -88,7 +88,7 @@ suite "folds (reduces) the given list from the right with a function": check foldr(@[1, 2, 3, 4], function, 5) == 15 test "direction dependent function applied to non-empty list": - func function(x: int, y: int): int | float = x - y + func function(x: int, y: int): int = x - y check foldr(@[1, 2, 3, 4], function, 24) == 14 test "empty list": From 231798df0053a2d78dc0d195cef7b80c0bbf2ae3 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:18 +0100 Subject: [PATCH 23/24] exercises(list-ops): example: use `toOpenArray`, not slicing --- exercises/practice/list-ops/.meta/example.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/practice/list-ops/.meta/example.nim b/exercises/practice/list-ops/.meta/example.nim index e29b45fe..bbca1933 100644 --- a/exercises/practice/list-ops/.meta/example.nim +++ b/exercises/practice/list-ops/.meta/example.nim @@ -34,14 +34,14 @@ func foldl*(list: openArray[int], function: proc(x, y: int): int {.noSideEffect. if list.len == 0: accumulator else: - foldl(list[1..^1], function, function(accumulator, list[0])) + foldl(list.toOpenArray(1, list.high), function, function(accumulator, list[0])) func foldr*(list: openArray[int], function: proc(x, y: int): int {.noSideEffect.}, accumulator: int): int = if list.len == 0: accumulator else: - function(foldr(list[1..^1], function, accumulator), list[0]) + function(foldr(list.toOpenArray(1, list.high), function, accumulator), list[0]) func reverse*(list: openArray[int]): seq[int] = result = newSeq[int](list.len) From ce422d4eb99535cd1b1465d570bdca9f6b6e7b27 Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:25:19 +0100 Subject: [PATCH 24/24] exercises(list-ops): tests.toml: exclude unimplemented test cases --- exercises/practice/list-ops/.meta/tests.toml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/exercises/practice/list-ops/.meta/tests.toml b/exercises/practice/list-ops/.meta/tests.toml index 16a0fca6..203ce1e3 100644 --- a/exercises/practice/list-ops/.meta/tests.toml +++ b/exercises/practice/list-ops/.meta/tests.toml @@ -27,8 +27,9 @@ description = "concatenate a list of lists -> empty list" [331451c1-9573-42a1-9869-2d06e3b389a9] description = "concatenate a list of lists -> list of lists" -# [d6ecd72c-197f-40c3-89a4-aa1f45827e09] -# description = "concatenate a list of lists -> list of nested lists" +[d6ecd72c-197f-40c3-89a4-aa1f45827e09] +description = "concatenate a list of lists -> list of nested lists" +include = false [0524fba8-3e0f-4531-ad2b-f7a43da86a16] description = "filter list returning only values that satisfy the filter function -> empty list" @@ -102,5 +103,6 @@ description = "reverse the elements of the list -> empty list" [fcc03d1e-42e0-4712-b689-d54ad761f360] description = "reverse the elements of the list -> non-empty list" -# [40872990-b5b8-4cb8-9085-d91fc0d05d26] -# description = "reverse the elements of the list -> list of lists is not flattened" +[40872990-b5b8-4cb8-9085-d91fc0d05d26] +description = "reverse the elements of the list -> list of lists is not flattened" +include = false