Skip to content

Commit 007b036

Browse files
committed
Add strain exercise
1 parent 0d763f0 commit 007b036

File tree

11 files changed

+429
-0
lines changed

11 files changed

+429
-0
lines changed

config.json

+8
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,14 @@
323323
"prerequisites": [],
324324
"difficulty": 1
325325
},
326+
{
327+
"slug": "strain",
328+
"name": "Strain",
329+
"uuid": "5a1a2fa9-e8d0-4784-ba0c-c53fb8405e26",
330+
"practices": [],
331+
"prerequisites": [],
332+
"difficulty": 2
333+
},
326334
{
327335
"slug": "sum-of-multiples",
328336
"name": "Sum of Multiples",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Instructions
2+
3+
Implement the `keep` and `discard` operation on collections.
4+
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.
5+
6+
For example, given the collection of numbers:
7+
8+
- 1, 2, 3, 4, 5
9+
10+
And the predicate:
11+
12+
- is the number even?
13+
14+
Then your keep operation should produce:
15+
16+
- 2, 4
17+
18+
While your discard operation should produce:
19+
20+
- 1, 3, 5
21+
22+
Note that the union of keep and discard is all the elements.
23+
24+
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.
25+
26+
## Restrictions
27+
28+
Keep your hands off that filter/reject/whatchamacallit functionality provided by your standard library!
29+
Solve this one yourself using other basic tools instead.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Here is an example solution for the Strain exercise
3+
*/
4+
component {
5+
6+
/**
7+
* @returns
8+
*/
9+
function keep(list, predicate) {
10+
var results = [];
11+
for (elem in list) {
12+
if (predicate(elem)) {
13+
arrayAppend(results, elem);
14+
}
15+
}
16+
17+
return results;
18+
}
19+
20+
/**
21+
* @returns
22+
*/
23+
function discard(list, predicate) {
24+
var newPredicate = function( x ) {return not predicate(x); }
25+
return keep(list, newPredicate);
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
component extends="StrainTest" {
2+
3+
function beforeAll(){
4+
SUT = createObject( 'Solution' );
5+
}
6+
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"BNAndras"
4+
],
5+
"files": {
6+
"solution": [
7+
"Strain.cfc"
8+
],
9+
"test": [
10+
"StrainTest.cfc"
11+
],
12+
"example": [
13+
".meta/Example.cfc"
14+
]
15+
},
16+
"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.",
17+
"source": "Conversation with James Edward Gray II",
18+
"source_url": "http://graysoftinc.com/"
19+
}
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[26af8c32-ba6a-4eb3-aa0a-ebd8f136e003]
13+
description = "keep on empty list returns empty list"
14+
15+
[f535cb4d-e99b-472a-bd52-9fa0ffccf454]
16+
description = "keeps everything"
17+
18+
[950b8e8e-f628-42a8-85e2-9b30f09cde38]
19+
description = "keeps nothing"
20+
21+
[92694259-6e76-470c-af87-156bdf75018a]
22+
description = "keeps first and last"
23+
24+
[938f7867-bfc7-449e-a21b-7b00cbb56994]
25+
description = "keeps neither first nor last"
26+
27+
[8908e351-4437-4d2b-a0f7-770811e48816]
28+
description = "keeps strings"
29+
30+
[2728036b-102a-4f1e-a3ef-eac6160d876a]
31+
description = "keeps lists"
32+
33+
[ef16beb9-8d84-451a-996a-14e80607fce6]
34+
description = "discard on empty list returns empty list"
35+
36+
[2f42f9bc-8e06-4afe-a222-051b5d8cd12a]
37+
description = "discards everything"
38+
39+
[ca990fdd-08c2-4f95-aa50-e0f5e1d6802b]
40+
description = "discards nothing"
41+
42+
[71595dae-d283-48ca-a52b-45fa96819d2f]
43+
description = "discards first and last"
44+
45+
[ae141f79-f86d-4567-b407-919eaca0f3dd]
46+
description = "discards neither first nor last"
47+
48+
[daf25b36-a59f-4f29-bcfe-302eb4e43609]
49+
description = "discards strings"
50+
51+
[a38d03f9-95ad-4459-80d1-48e937e4acaf]
52+
description = "discards lists"

exercises/practice/strain/Strain.cfc

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Your implementation of the Strain exercise
3+
*/
4+
component {
5+
6+
/**
7+
* @returns
8+
*/
9+
function keep(list, predicate) {
10+
// Implement me here
11+
}
12+
13+
/**
14+
* @returns
15+
*/
16+
function discard(list, predicate) {
17+
// Implement me here
18+
}
19+
}
+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
component extends="testbox.system.BaseSpec" {
2+
3+
function beforeAll(){
4+
SUT = createObject( 'Strain' );
5+
}
6+
7+
function alwaysTrue( x ) { return true; }
8+
9+
function alwaysFalse( x ) { return false; }
10+
11+
function isOdd( x ) { return x % 2 == 1; }
12+
13+
function isEven( x ) { return x % 2 == 0; }
14+
15+
function containsFive( x ) { return arrayContains(x, 5); }
16+
17+
function startWithZ( x ) { return left(x, 1) == 'z'; }
18+
19+
function run(){
20+
21+
describe( "My Strain class", function(){
22+
23+
it( 'keep on empty list returns empty list', function(){
24+
expect( SUT.keep( list=[], predicate=alwaysTrue ) ).toBe( [] );
25+
});
26+
27+
it( 'keeps everything', function(){
28+
expect( SUT.keep( list=[1, 3, 5], predicate=alwaysTrue ) ).toBe( [1,3,5] );
29+
});
30+
31+
it( 'keeps nothing', function(){
32+
expect( SUT.keep( list=[1, 3, 5], predicate=alwaysFalse) ).toBe( [] );
33+
});
34+
35+
it( 'keeps first and last', function(){
36+
expect( SUT.keep( list=[1, 2, 3], predicate=isOdd ) ).toBe( [1,3] );
37+
});
38+
39+
it( 'keeps neither first nor last', function(){
40+
expect( SUT.keep( list=[1, 2, 3], predicate=isEven ) ).toBe( [2] );
41+
});
42+
43+
it( 'keeps strings', function(){
44+
expect( SUT.keep(
45+
list=["apple",
46+
"zebra",
47+
"banana",
48+
"zombies",
49+
"cherimoya",
50+
"zealot"],
51+
predicate=startWithZ ) ).toBe( ["zebra","zombies","zealot"] );
52+
});
53+
54+
it( 'keeps lists', function(){
55+
expect( SUT.keep(
56+
list=[[1, 2, 3],
57+
[5, 5, 5],
58+
[5, 1, 2],
59+
[2, 1, 2],
60+
[1, 5, 2],
61+
[2, 2, 1],
62+
[1, 2, 5]],
63+
predicate=containsFive ) ).toBe( [[5,5,5],
64+
[5,1,2],
65+
[1,5,2],
66+
[1,2,5]] );
67+
});
68+
69+
it( 'discard on empty list returns empty list', function(){
70+
expect( SUT.discard( list=[], predicate=alwaysTrue ) ).toBe( [] );
71+
});
72+
73+
it( 'discards everything', function(){
74+
expect( SUT.discard( list=[1, 3, 5], predicate=alwaysTrue ) ).toBe( [] );
75+
});
76+
77+
it( 'discards nothing', function(){
78+
expect( SUT.discard( list=[1, 3, 5], predicate=alwaysFalse ) ).toBe( [1,3,5] );
79+
});
80+
81+
it( 'discards first and last', function(){
82+
expect( SUT.discard( list=[1, 2, 3], predicate=isOdd ) ).toBe( [2] );
83+
});
84+
85+
it( 'discards neither first nor last', function(){
86+
expect( SUT.discard( list=[1, 2, 3], predicate=isEven ) ).toBe( [1,3] );
87+
});
88+
89+
it( 'discards strings', function(){
90+
expect( SUT.discard(
91+
list=["apple",
92+
"zebra",
93+
"banana",
94+
"zombies",
95+
"cherimoya",
96+
"zealot"],
97+
predicate=startWithZ ) ).toBe( ["apple",
98+
"banana",
99+
"cherimoya"] );
100+
});
101+
102+
it( 'discards lists', function(){
103+
expect( SUT.discard(
104+
list=[[1, 2, 3],
105+
[5, 5, 5],
106+
[5, 1, 2],
107+
[2, 1, 2],
108+
[1, 5, 2],
109+
[2, 2, 1],
110+
[1, 2, 5]],
111+
predicate=containsFive ) ).toBe( [[1,2,3],
112+
[2,1,2],
113+
[2,2,1]] );
114+
});
115+
116+
});
117+
118+
}
119+
120+
}containsFive

0 commit comments

Comments
 (0)