Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[List-ops]: Templated + synced #723

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions exercises/practice/list-ops/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ 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 using `function(accumulator, item)`*);
- `foldr` (*given a function, a list, and an initial accumulator, fold (reduce) each item into the accumulator from the right using `function(item, accumulator)`*);
- `reverse` (*given a list, return a list with all the original items, but in reversed order*);
- `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.
113 changes: 57 additions & 56 deletions exercises/practice/list-ops/.meta/Sources/ListOps/ListOpsExample.swift
Original file line number Diff line number Diff line change
@@ -1,81 +1,82 @@
struct ListOps {

static func append<T: Equatable>(_ array1: [T], _ array2: [T]) -> [T] {
var result = array1
for value in array2 {
result.append(value)
}

return result
static func append<T: Equatable>(_ array1: [T], _ array2: [T]) -> [T] {
var result = array1
for value in array2 {
result.append(value)
}

static func concat<T: Equatable>(_ arrays: [T]...) -> [T] {
var result = [T]()
return result
}

for array in arrays {
result = append(result, array)
}
static func concat<T: Equatable>(_ arrays: [T]...) -> [T] {
var result = [T]()

return result
for array in arrays {
result = append(result, array)
}

static func filter<T: Equatable>(_ array: [T], predicate: (T) -> Bool) -> [T] {
var filtered = [T]()
for value in array {
if predicate(value) {
filtered.append(value)
}
}
return result
}

return filtered
static func filter<T: Equatable>(_ array: [T], predicate: (T) -> Bool) -> [T] {
var filtered = [T]()
for value in array {
if predicate(value) {
filtered.append(value)
}
}

static func length<T>(_ array: [T]) -> Int {
var length = 0
return filtered
}

for _ in array {
length += 1
}
static func length<T>(_ array: [T]) -> Int {
var length = 0

return length
for _ in array {
length += 1
}

static func map<T: Equatable>(_ array: [T], transform: (T) -> T) -> [T] {
var result = [T]()
return length
}

for value in array {
result.append(transform(value))
}
static func map<T: Equatable>(_ array: [T], transform: (T) -> T) -> [T] {
var result = [T]()

return result
for value in array {
result.append(transform(value))
}

static func foldLeft<T: Equatable>(_ array: [T], accumulated: T, combine: (T, T) -> T) -> T {
if length(array) == 0 {
return accumulated
} else {
return foldLeft(Array(array.dropFirst()), accumulated: combine(accumulated, array[0]), combine: combine)
}
}
return result
}

static func foldRight<T: Equatable>(_ array: [T], accumulated: T, combine: (T, T) -> T) -> T {
if length(array) == 0 {
return accumulated
} else {
return combine(array[0], foldRight(Array(array.dropFirst()), accumulated: accumulated, combine: combine))
}
static func foldLeft<T: Equatable>(_ array: [T], accumulated: T, combine: (T, T) -> T) -> T {
if length(array) == 0 {
return accumulated
} else {
return foldLeft(
Array(array.dropFirst()), accumulated: combine(accumulated, array[0]), combine: combine)
}
}

static func foldRight<T: Equatable>(_ array: [T], accumulated: T, combine: (T, T) -> T) -> T {
if length(array) == 0 {
return accumulated
} else {
return combine(
array[0], foldRight(Array(array.dropFirst()), accumulated: accumulated, combine: combine))
}
}

static func reverse<T: Equatable>(_ array: [T]) -> [T] {
var result = [T]()
var index = length(array) - 1

while index >= 0 {
result.append(array[index])
index -= 1
}
static func reverse<T: Equatable>(_ array: [T]) -> [T] {
var result = [T]()
var index = length(array) - 1

return result
while index >= 0 {
result.append(array[index])
index -= 1
}

return result
}

}
62 changes: 62 additions & 0 deletions exercises/practice/list-ops/.meta/template.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import XCTest
@testable import {{exercise|camelCase}}
class {{exercise|camelCase}}Tests: XCTestCase {
let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false

{% outer: for case in cases %}
{%- for subCases in case.cases %}
{%- if forloop.outer.first and forloop.first %}
func test{{subCases.description |camelCase }}{{ forloop.outer.counter }}{{ forloop.counter }}() {
{%- else %}
func test{{subCases.description |camelCase }}{{ forloop.outer.counter }}{{ forloop.counter }}() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
{%- endif %}
{%- if subCases.property == "append" %}
let input1 : [Int] = {{ subCases.input.list1 }}
let input2 : [Int]= {{ subCases.input.list2 }}
let expected : [Int] = {{ subCases.expected }}
XCTAssertEqual(ListOps.append(input1, input2), expected)
{%- elif subCases.property == "concat" %}
{%- ifnot subCases.expected %}
let expected = [Int]()
{%- else %}
let expected = {{ subCases.expected }}
{%- endif %}
XCTAssertEqual(ListOps.concat({% ifnot subCases.input.lists %}[]{% endif %} {% for list in subCases.input.lists %}{% ifnot forloop.first %},{% endif %}{{list}} {% endfor %}), expected)
{%- elif subCases.property == "filter" %}
let input : [Int] = {{ subCases.input.list }}
let expected : [Int] = {{ subCases.expected }}
XCTAssertEqual(ListOps.filter(input) {{subCases.input.function | listOps}}, expected)
{%- elif subCases.property == "length" %}
let input : [Int] = {{ subCases.input.list }}
let expected : Int = {{ subCases.expected }}
XCTAssertEqual(ListOps.length(input), expected)
{%- elif subCases.property == "map" %}
let input : [Int] = {{ subCases.input.list }}
let expected : [Int] = {{ subCases.expected }}
XCTAssertEqual(ListOps.map(input) {{subCases.input.function | listOps}} , expected)
{%- elif subCases.property == "foldl" %}
let input : [Int] = {{ subCases.input.list }}
let expected : Int = {{ subCases.expected }}
XCTAssertEqual(ListOps.foldLeft(input, accumulated: {{ subCases.input.initial }}, combine: {{ subCases.input.function | listOps }}), expected)
{%- elif subCases.property == "foldr" %}
let input : [Int] = {{ subCases.input.list }}
let expected : Int = {{ subCases.expected }}
XCTAssertEqual(ListOps.foldRight(input, accumulated: {{ subCases.input.initial }}, combine: {{ subCases.input.function | listOps }}), expected)
{%- elif subCases.property == "reverse" %}
{%- ifnot subCases.input.list %}
let input = [Int]()
{%- else %}
let input = {{ subCases.input.list }}
{%- endif %}
{%- ifnot subCases.expected %}
let expected = [Int]()
{%- else %}
let expected = {{ subCases.expected }}
{%- endif %}
XCTAssertEqual(ListOps.reverse(input), expected)
{%- endif %}
}
{% endfor -%}
{% endfor -%}
}
21 changes: 8 additions & 13 deletions exercises/practice/list-ops/.meta/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
# 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"

Expand All @@ -36,9 +33,6 @@ description = "filter list returning only values that satisfy the filter functio
[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"

Expand All @@ -50,16 +44,15 @@ description = "return a list of elements whose values equal the list value trans

[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"

[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"
include = false

[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"
Expand All @@ -68,15 +61,19 @@ 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"
include = false # Decided to remove this one to keep compatabillity

[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"
Expand All @@ -89,12 +86,10 @@ 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"
include = false # Decided to remove this one to keep compatabillity

[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"
30 changes: 15 additions & 15 deletions exercises/practice/list-ops/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
import PackageDescription

let package = Package(
name: "ListOps",
products: [
.library(
name: "ListOps",
targets: ["ListOps"]),
],
dependencies: [],
targets: [
.target(
name: "ListOps",
dependencies: []),
.testTarget(
name: "ListOpsTests",
dependencies: ["ListOps"]),
]
name: "ListOps",
products: [
.library(
name: "ListOps",
targets: ["ListOps"])
],
dependencies: [],
targets: [
.target(
name: "ListOps",
dependencies: []),
.testTarget(
name: "ListOpsTests",
dependencies: ["ListOps"]),
]
)
4 changes: 3 additions & 1 deletion exercises/practice/list-ops/Sources/ListOps/ListOps.swift
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
//Solution goes in Sources
struct ListOps {
// Write your code for the 'ListOps' exercise in this file.
}
Loading
Loading