Skip to content

Commit

Permalink
Add strain exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
keiravillekode committed Nov 29, 2023
1 parent f91afda commit 21ab039
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,14 @@
"prerequisites": [],
"difficulty": 3
},
{
"slug": "strain",
"name": "Strain",
"uuid": "2da79b0f-d182-46c7-a4e4-f0246a0fad65",
"practices": [],
"prerequisites": [],
"difficulty": 3
},
{
"slug": "connect",
"name": "Connect",
Expand Down
29 changes: 29 additions & 0 deletions exercises/practice/strain/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Instructions

Implement the `keep` and `discard` operation on collections.
Given a collection and a predicate on the collection's elements, `keep` returns a new collection containing those elements where the predicate is true, while `discard` returns a new collection containing those elements where the predicate is false.

For example, given the collection of numbers:

- 1, 2, 3, 4, 5

And the predicate:

- is the number even?

Then your keep operation should produce:

- 2, 4

While your discard operation should produce:

- 1, 3, 5

Note that the union of keep and discard is all the elements.

The functions may be called `keep` and `discard`, or they may need different names in order to not clash with existing functions or concepts in your language.

## Restrictions

Keep your hands off that filter/reject/whatchamacallit functionality provided by your standard library!
Solve this one yourself using other basic tools instead.
19 changes: 19 additions & 0 deletions exercises/practice/strain/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"keiravillekode"
],
"files": {
"solution": [
"strain.v"
],
"test": [
"run_test.v"
],
"example": [
".meta/example.v"
]
},
"blurb": "Implement the `keep` and `discard` operation on collections. Given a collection and a predicate on the collection's elements, `keep` returns a new collection containing those elements where the predicate is true, while `discard` returns a new collection containing those elements where the predicate is false.",
"source": "Conversation with James Edward Gray II",
"source_url": "http://graysoftinc.com/"
}
25 changes: 25 additions & 0 deletions exercises/practice/strain/.meta/example.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module main

pub fn keep[T](array []T, predicate fn (e T) bool) []T {
mut result := []T{cap: array.len}

for element in array {
if predicate(element) {
result << element
}
}

return result
}

pub fn discard[T](array []T, predicate fn (e T) bool) []T {
mut result := []T{cap: array.len}

for element in array {
if !predicate(element) {
result << element
}
}

return result
}
45 changes: 45 additions & 0 deletions exercises/practice/strain/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This is an auto-generated file. Regular comments will be removed when this
# file is regenerated. Regenerating will not touch any manually added keys,
# so comments can be added in a "comment" key.

[26af8c32-ba6a-4eb3-aa0a-ebd8f136e003]
description = "keep on empty list returns empty list"

[f535cb4d-e99b-472a-bd52-9fa0ffccf454]
description = "keeps everything"

[950b8e8e-f628-42a8-85e2-9b30f09cde38]
description = "keeps nothing"

[92694259-6e76-470c-af87-156bdf75018a]
description = "keeps first and last"

[938f7867-bfc7-449e-a21b-7b00cbb56994]
description = "keeps neither first nor last"

[8908e351-4437-4d2b-a0f7-770811e48816]
description = "keeps strings"

[2728036b-102a-4f1e-a3ef-eac6160d876a]
description = "keeps lists"

[ef16beb9-8d84-451a-996a-14e80607fce6]
description = "discard on empty list returns empty list"

[2f42f9bc-8e06-4afe-a222-051b5d8cd12a]
description = "discards everything"

[ca990fdd-08c2-4f95-aa50-e0f5e1d6802b]
description = "discards nothing"

[71595dae-d283-48ca-a52b-45fa96819d2f]
description = "discards first and last"

[ae141f79-f86d-4567-b407-919eaca0f3dd]
description = "discards neither first nor last"

[daf25b36-a59f-4f29-bcfe-302eb4e43609]
description = "discards strings"

[a38d03f9-95ad-4459-80d1-48e937e4acaf]
description = "discards lists"
148 changes: 148 additions & 0 deletions exercises/practice/strain/run_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
module main

const empty = []int{cap: 0}

fn test_keep_on_empty_list_returns_empty_list() {
predicate := fn (x int) bool {
return true
}
assert keep(empty, predicate) == empty
}

fn test_keeps_everything() {
array := [1, 3, 5]
predicate := fn (x int) bool {
return true
}
expect := [1, 3, 5]
assert keep(array, predicate) == expect
}

fn test_keeps_nothing() {
array := [1, 3, 5]
predicate := fn (x int) bool {
return false
}
assert keep(array, predicate) == empty
}

fn test_keeps_first_and_last() {
array := [1, 2, 3]
predicate := fn (x int) bool {
return x % 2 == 1
}
expect := [1, 3]
assert keep(array, predicate) == expect
}

fn test_keeps_neither_first_nor_last() {
array := [1, 2, 3]
predicate := fn (x int) bool {
return x % 2 == 0
}
expect := [2]
assert keep(array, predicate) == expect
}

fn test_keeps_strings() {
array := ['apple', 'zebra', 'banana', 'zombies', 'cherimoya', 'zealot']
predicate := fn (x string) bool {
return x.starts_with('z')
}
expect := ['zebra', 'zombies', 'zealot']
assert keep(array, predicate) == expect
}

fn test_keeps_lists() {
array := [
[1, 2, 3],
[5, 5, 5],
[5, 1, 2],
[2, 1, 2],
[1, 5, 2],
[2, 2, 1],
[1, 2, 5],
]
predicate := fn (x []int) bool {
return x.contains(5)
}
expect := [
[5, 5, 5],
[5, 1, 2],
[1, 5, 2],
[1, 2, 5],
]
assert keep(array, predicate) == expect
}

fn test_discard_on_empty_list_returns_empty_list() {
predicate := fn (x int) bool {
return true
}
assert discard(empty, predicate) == empty
}

fn test_discards_everything() {
array := [1, 3, 5]
predicate := fn (x int) bool {
return true
}
assert discard(array, predicate) == empty
}

fn test_discards_nothing() {
array := [1, 3, 5]
predicate := fn (x int) bool {
return false
}
expect := [1, 3, 5]
assert discard(array, predicate) == expect
}

fn test_discards_first_and_last() {
array := [1, 2, 3]
predicate := fn (x int) bool {
return x % 2 == 1
}
expect := [2]
assert discard(array, predicate) == expect
}

fn test_discards_neither_first_nor_last() {
array := [1, 2, 3]
predicate := fn (x int) bool {
return x % 2 == 0
}
expect := [1, 3]
assert discard(array, predicate) == expect
}

fn test_discards_strings() {
array := ['apple', 'zebra', 'banana', 'zombies', 'cherimoya', 'zealot']
predicate := fn (x string) bool {
return x.starts_with('z')
}
expect := ['apple', 'banana', 'cherimoya']
assert discard(array, predicate) == expect
}

fn test_discards_lists() {
array := [
[1, 2, 3],
[5, 5, 5],
[5, 1, 2],
[2, 1, 2],
[1, 5, 2],
[2, 2, 1],
[1, 2, 5],
]
predicate := fn (x []int) bool {
return x.contains(5)
}
expect := [
[1, 2, 3],
[2, 1, 2],
[2, 2, 1],
]
assert discard(array, predicate) == expect
}
7 changes: 7 additions & 0 deletions exercises/practice/strain/strain.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module main

pub fn keep[T](array []T, predicate fn (e T) bool) []T {
}

pub fn discard[T](array []T, predicate fn (e T) bool) []T {
}

0 comments on commit 21ab039

Please sign in to comment.