trackler 2.0.8.24 → 2.0.8.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/c/config.json +9 -0
- data/tracks/c/exercises/nucleotide-count/makefile +15 -0
- data/tracks/c/exercises/nucleotide-count/src/example.c +43 -0
- data/tracks/c/exercises/nucleotide-count/src/example.h +6 -0
- data/tracks/c/exercises/nucleotide-count/test/test_nucleotide_count.c +58 -0
- data/tracks/c/exercises/nucleotide-count/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/nucleotide-count/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/nucleotide-count/test/vendor/unity_internals.h +701 -0
- data/tracks/ceylon/README.md +2 -2
- data/tracks/csharp/.gitattributes +11 -0
- data/tracks/csharp/appveyor.yml +1 -4
- data/tracks/csharp/exercises/acronym/AcronymTest.cs +1 -1
- data/tracks/csharp/exercises/atbash-cipher/AtbashCipher.cs +8 -3
- data/tracks/csharp/exercises/atbash-cipher/AtbashCipherTest.cs +76 -0
- data/tracks/csharp/exercises/atbash-cipher/Example.cs +22 -23
- data/tracks/csharp/exercises/isogram/Example.cs +2 -2
- data/tracks/csharp/exercises/isogram/IsogramTest.cs +47 -15
- data/tracks/csharp/exercises/nth-prime/Example.cs +4 -1
- data/tracks/csharp/exercises/nth-prime/NthPrime.cs +1 -1
- data/tracks/csharp/exercises/nth-prime/NthPrimeTest.cs +29 -15
- data/tracks/csharp/exercises/perfect-numbers/Example.cs +14 -16
- data/tracks/csharp/exercises/perfect-numbers/PerfectNumbers.cs +2 -2
- data/tracks/csharp/exercises/perfect-numbers/PerfectNumbersTest.cs +78 -26
- data/tracks/csharp/exercises/pig-latin/PigLatinTest.cs +69 -24
- data/tracks/csharp/exercises/raindrops/Example.cs +1 -1
- data/tracks/csharp/exercises/raindrops/RaindropsTest.cs +93 -31
- data/tracks/csharp/exercises/roman-numerals/HINTS.md +2 -0
- data/tracks/csharp/exercises/roman-numerals/RomanNumeralsTest.cs +106 -23
- data/tracks/csharp/exercises/word-search/HINTS.md +6 -0
- data/tracks/csharp/generators/{TestClass.cs → Classes/TestClass.cs} +2 -1
- data/tracks/csharp/generators/{TestClassNameTransformer.cs → Classes/TestClassNameTransformer.cs} +1 -1
- data/tracks/csharp/generators/{TestClassRenderer.cs → Classes/TestClassRenderer.cs} +2 -1
- data/tracks/csharp/generators/Classes/TestedClassNameTransformer.cs +9 -0
- data/tracks/csharp/generators/{CanonicalData.cs → Data/CanonicalData.cs} +1 -1
- data/tracks/csharp/generators/{CanonicalDataCase.cs → Data/CanonicalDataCase.cs} +3 -3
- data/tracks/csharp/generators/{CanonicalDataCaseJsonConverter.cs → Data/CanonicalDataCaseJsonConverter.cs} +1 -1
- data/tracks/csharp/generators/{CanonicalDataCasesJsonConverter.cs → Data/CanonicalDataCasesJsonConverter.cs} +2 -2
- data/tracks/csharp/generators/{CanonicalDataParser.cs → Data/CanonicalDataParser.cs} +5 -5
- data/tracks/csharp/generators/{ExerciseCollection.cs → Data/ExerciseCollection.cs} +3 -3
- data/tracks/csharp/generators/Exercises/AcronymExercise.cs +20 -0
- data/tracks/csharp/generators/Exercises/AtbashCipherExercise.cs +20 -0
- data/tracks/csharp/generators/Exercises/BooleanExercise.cs +14 -0
- data/tracks/csharp/generators/Exercises/EqualityExercise.cs +14 -0
- data/tracks/csharp/generators/Exercises/Exercise.cs +59 -4
- data/tracks/csharp/generators/Exercises/IsogramExercise.cs +9 -0
- data/tracks/csharp/generators/Exercises/LeapExercise.cs +1 -4
- data/tracks/csharp/generators/Exercises/NthPrimeExercise.cs +25 -0
- data/tracks/csharp/generators/Exercises/PerfectNumbersExercise.cs +29 -0
- data/tracks/csharp/generators/Exercises/PigLatinExercise.cs +9 -0
- data/tracks/csharp/generators/Exercises/RaindropsExercise.cs +20 -0
- data/tracks/csharp/generators/Exercises/RomanNumeralsExercise.cs +30 -0
- data/tracks/csharp/generators/Helpers/StringExtensions.cs +8 -0
- data/tracks/csharp/generators/{To.cs → Helpers/To.cs} +4 -1
- data/tracks/csharp/generators/Methods/BooleanTestMethodGenerator.cs +32 -0
- data/tracks/csharp/generators/Methods/EqualityTestMethodGenerator.cs +25 -0
- data/tracks/csharp/generators/Methods/ExceptionTestMethodGenerator.cs +30 -0
- data/tracks/csharp/generators/{TestMethod.cs → Methods/TestMethod.cs} +6 -3
- data/tracks/csharp/generators/Methods/TestMethodData.cs +12 -0
- data/tracks/csharp/generators/Methods/TestMethodGenerator.cs +64 -0
- data/tracks/csharp/generators/Methods/TestMethodNameTransformer.cs +23 -0
- data/tracks/csharp/generators/Methods/TestMethodOptions.cs +13 -0
- data/tracks/csharp/generators/{TestMethodRenderer.cs → Methods/TestMethodRenderer.cs} +1 -1
- data/tracks/csharp/generators/{TestedMethodNameTransformer.cs → Methods/TestedMethodNameTransformer.cs} +1 -1
- data/tracks/csharp/generators/Methods/TestedMethodType.cs +9 -0
- data/tracks/csharp/generators/Program.cs +2 -0
- data/tracks/elixir/config.json +7 -0
- data/tracks/elixir/exercises/diffie-hellman/HINTS.md +10 -0
- data/tracks/elixir/exercises/diffie-hellman/diffie_hellman.exs +61 -0
- data/tracks/elixir/exercises/diffie-hellman/diffie_hellman_test.exs +99 -0
- data/tracks/elixir/exercises/diffie-hellman/example.exs +64 -0
- data/tracks/haskell/exercises/pov/src/POV.hs +2 -2
- data/tracks/haskell/exercises/pythagorean-triplet/src/Triplet.hs +6 -3
- data/tracks/haskell/exercises/queen-attack/src/Queens.hs +1 -1
- data/tracks/haskell/exercises/raindrops/src/Raindrops.hs +2 -1
- data/tracks/haskell/exercises/robot-name/src/Robot.hs +2 -2
- data/tracks/haskell/exercises/robot-simulator/src/Robot.hs +6 -6
- data/tracks/haskell/exercises/roman-numerals/src/Roman.hs +2 -1
- data/tracks/haskell/exercises/run-length-encoding/src/RunLength.hs +2 -2
- data/tracks/haskell/exercises/saddle-points/src/Matrix.hs +2 -1
- data/tracks/haskell/exercises/say/src/Say.hs +2 -1
- data/tracks/haskell/exercises/scrabble-score/src/Scrabble.hs +4 -2
- data/tracks/haskell/exercises/secret-handshake/src/SecretHandshake.hs +1 -1
- data/tracks/haskell/exercises/sgf-parsing/src/Sgf.hs +1 -1
- data/tracks/java/exercises/acronym/src/example/java/Acronym.java +11 -1
- data/tracks/java/exercises/acronym/src/test/java/AcronymTest.java +8 -9
- data/tracks/java/exercises/grade-school/src/test/java/SchoolTest.java +8 -2
- data/tracks/java/exercises/luhn/src/test/java/LuhnValidatorTest.java +20 -13
- data/tracks/java/exercises/robot-name/src/test/java/RobotTest.java +6 -1
- data/tracks/javascript/README.md +1 -1
- data/tracks/javascript/docs/TESTS.md +9 -1
- data/tracks/kotlin/exercises/luhn/src/example/kotlin/Luhn.kt +18 -26
- data/tracks/kotlin/exercises/luhn/src/test/kotlin/LuhnTest.kt +40 -38
- data/tracks/php/README.md +1 -1
- data/tracks/php/config.json +5 -0
- data/tracks/php/exercises/perfect-numbers/example.php +23 -0
- data/tracks/php/exercises/perfect-numbers/perfect-numbers_test.php +99 -0
- data/tracks/purescript/.travis.yml +1 -0
- data/tracks/purescript/bin/test.sh +33 -8
- data/tracks/purescript/config.json +7 -0
- data/tracks/purescript/exercises/meetup/bower.json +17 -0
- data/tracks/purescript/exercises/meetup/examples/src/Meetup.purs +37 -0
- data/tracks/purescript/exercises/meetup/src/Meetup.purs +11 -0
- data/tracks/purescript/exercises/meetup/test/Main.purs +395 -0
- data/tracks/python/README.md +7 -6
- data/tracks/python/docs/TOOLS.md +3 -3
- data/tracks/python/exercises/bracket-push/bracket_push_test.py +32 -15
- data/tracks/python/exercises/hamming/hamming_test.py +2 -0
- data/tracks/python/exercises/luhn/luhn_test.py +2 -0
- data/tracks/python/test/check-exercises.py +7 -1
- metadata +56 -20
- data/tracks/csharp/exercises/atbash-cipher/AtbashTest.cs +0 -17
- data/tracks/csharp/generators/BooleanTestMethod.cs +0 -36
- data/tracks/csharp/generators/TestMethodNameTransformer.cs +0 -11
- data/tracks/csharp/generators/TestedClassNameTransformer.cs +0 -11
- data/tracks/java/exercises/allergies/src/main/java/.keep +0 -0
@@ -1,86 +1,88 @@
|
|
1
1
|
import org.junit.Test
|
2
2
|
import org.junit.Ignore
|
3
|
-
import kotlin.test.
|
3
|
+
import kotlin.test.assertFalse
|
4
|
+
import kotlin.test.assertTrue
|
4
5
|
|
5
6
|
class LuhnTest {
|
6
7
|
|
7
8
|
|
8
9
|
@Test
|
9
|
-
fun
|
10
|
-
|
11
|
-
|
12
|
-
assertEquals(expectedOutput, Luhn(34567).checkDigit)
|
10
|
+
fun singleDigitStringsCannotBeValid() {
|
11
|
+
assertFalse(Luhn.isValid("1"))
|
13
12
|
}
|
14
13
|
|
15
14
|
@Ignore
|
16
15
|
@Test
|
17
|
-
fun
|
18
|
-
|
19
|
-
|
20
|
-
assertEquals(expectedOutput, Luhn(12121).addends)
|
16
|
+
fun singleZeroIsInvalid() {
|
17
|
+
assertFalse(Luhn.isValid("0"))
|
21
18
|
}
|
22
19
|
|
23
20
|
@Ignore
|
24
21
|
@Test
|
25
|
-
fun
|
26
|
-
|
27
|
-
|
28
|
-
assertEquals(expectedOutput, Luhn(8631).addends)
|
22
|
+
fun simpleValidSINThatRemainsValidIfReversed() {
|
23
|
+
assertTrue(Luhn.isValid("059"))
|
24
|
+
assertTrue(Luhn.isValid("950"))
|
29
25
|
}
|
30
26
|
|
31
27
|
@Ignore
|
32
28
|
@Test
|
33
|
-
fun
|
34
|
-
|
35
|
-
|
36
|
-
assertEquals(expectedOutput, Luhn(4913).checksum)
|
29
|
+
fun simpleValidSINThatBecomesInvalidIfReversed() {
|
30
|
+
assertTrue(Luhn.isValid("59"))
|
31
|
+
assertFalse(Luhn.isValid("95"))
|
37
32
|
}
|
38
33
|
|
39
34
|
@Ignore
|
40
35
|
@Test
|
41
|
-
fun
|
42
|
-
|
43
|
-
|
44
|
-
assertEquals(expectedOutput, Luhn(201773).checksum)
|
36
|
+
fun validCanadianSIN() {
|
37
|
+
assertTrue(Luhn.isValid("055 444 285"))
|
45
38
|
}
|
46
39
|
|
47
40
|
@Ignore
|
48
41
|
@Test
|
49
|
-
fun
|
50
|
-
|
51
|
-
|
52
|
-
assertEquals(expectedOutput, Luhn(738).isValid)
|
42
|
+
fun invalidCanadianSIN() {
|
43
|
+
assertFalse(Luhn.isValid("055 444 286"))
|
53
44
|
}
|
54
45
|
|
55
46
|
@Ignore
|
56
47
|
@Test
|
57
|
-
fun
|
58
|
-
|
59
|
-
|
60
|
-
assertEquals(expectedOutput, Luhn(8739567).isValid)
|
48
|
+
fun invalidCreditCard() {
|
49
|
+
assertFalse(Luhn.isValid("8273 1232 7352 0569"))
|
61
50
|
}
|
62
51
|
|
63
52
|
@Ignore
|
64
53
|
@Test
|
65
|
-
fun
|
66
|
-
|
54
|
+
fun validStringsWithNonDigitIncludedBecomeInvalid() {
|
55
|
+
assertFalse(Luhn.isValid("055a 444 285"))
|
56
|
+
}
|
67
57
|
|
68
|
-
|
58
|
+
@Ignore
|
59
|
+
@Test
|
60
|
+
fun validStringsWithPunctuationIncludedBecomeInvalid() {
|
61
|
+
assertFalse(Luhn.isValid("055-444-285"))
|
69
62
|
}
|
70
63
|
|
71
64
|
@Ignore
|
72
65
|
@Test
|
73
|
-
fun
|
74
|
-
|
66
|
+
fun validStringsWithSymbolsIncludedBecomeInvalid() {
|
67
|
+
assertFalse(Luhn.isValid("055£ 444$ 285"))
|
68
|
+
}
|
75
69
|
|
76
|
-
|
70
|
+
@Ignore
|
71
|
+
@Test
|
72
|
+
fun singleZeroWithSpaceIsInvalid() {
|
73
|
+
assertFalse(Luhn.isValid(" 0"))
|
77
74
|
}
|
78
75
|
|
79
76
|
@Ignore
|
80
77
|
@Test
|
81
|
-
fun
|
82
|
-
|
78
|
+
fun moreThanSingleZeroIsValid() {
|
79
|
+
assertTrue(Luhn.isValid("0000 0"))
|
80
|
+
}
|
83
81
|
|
84
|
-
|
82
|
+
@Ignore
|
83
|
+
@Test
|
84
|
+
fun inputDigit9IsCorrectlyConvertedToOutputDigit9() {
|
85
|
+
assertTrue(Luhn.isValid("091"))
|
85
86
|
}
|
87
|
+
|
86
88
|
}
|
data/tracks/php/README.md
CHANGED
data/tracks/php/config.json
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
function getClassification($number)
|
4
|
+
{
|
5
|
+
if ($number <= 0) {
|
6
|
+
throw new InvalidArgumentException("You must supply a natural number (positive integer)");
|
7
|
+
}
|
8
|
+
|
9
|
+
$sum = 0 ;
|
10
|
+
for ($i = 1; $i < $number; $i++) {
|
11
|
+
if ($number % $i == 0) {
|
12
|
+
$sum += $i ;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
if ($sum == $number) {
|
17
|
+
return "perfect" ;
|
18
|
+
} elseif ($sum < $number) {
|
19
|
+
return "deficient" ;
|
20
|
+
} else {
|
21
|
+
return "abundant" ;
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,99 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
require "perfect-numbers.php";
|
4
|
+
|
5
|
+
class PerfectNumbersTest extends PHPUnit\Framework\TestCase
|
6
|
+
{
|
7
|
+
public function testSmallPerfectNumberIsClassifiedCorrectly()
|
8
|
+
{
|
9
|
+
$this->assertEquals("perfect", getClassification(6));
|
10
|
+
}
|
11
|
+
|
12
|
+
public function testMediumPerfectNumberIsClassifiedCorrectly()
|
13
|
+
{
|
14
|
+
$this->markTestSkipped();
|
15
|
+
|
16
|
+
$this->assertEquals("perfect", getClassification(28));
|
17
|
+
}
|
18
|
+
|
19
|
+
public function testLargePerfectNumberIsClassifiedCorrectly()
|
20
|
+
{
|
21
|
+
$this->markTestSkipped();
|
22
|
+
|
23
|
+
$this->assertEquals("perfect", getClassification(33550336));
|
24
|
+
}
|
25
|
+
|
26
|
+
public function testSmallAbundantNumberIsClassifiedCorrectly()
|
27
|
+
{
|
28
|
+
$this->markTestSkipped();
|
29
|
+
|
30
|
+
$this->assertEquals("abundant", getClassification(12));
|
31
|
+
}
|
32
|
+
|
33
|
+
public function testMediumAbundantNumberIsClassifiedCorrectly()
|
34
|
+
{
|
35
|
+
$this->markTestSkipped();
|
36
|
+
|
37
|
+
$this->assertEquals("abundant", getClassification(30));
|
38
|
+
}
|
39
|
+
|
40
|
+
public function testLargeAbundantNumberIsClassifiedCorrectly()
|
41
|
+
{
|
42
|
+
$this->markTestSkipped();
|
43
|
+
|
44
|
+
$this->assertEquals("abundant", getClassification(33550335));
|
45
|
+
}
|
46
|
+
|
47
|
+
public function testSmallestPrimeDeficientNumberIsClassifiedCorrectly()
|
48
|
+
{
|
49
|
+
$this->markTestSkipped();
|
50
|
+
|
51
|
+
$this->assertEquals("deficient", getClassification(2));
|
52
|
+
}
|
53
|
+
|
54
|
+
public function testSmallestNonPrimeDeficientNumberIsClassifiedCorrectly()
|
55
|
+
{
|
56
|
+
$this->markTestSkipped();
|
57
|
+
|
58
|
+
$this->assertEquals("deficient", getClassification(4));
|
59
|
+
}
|
60
|
+
|
61
|
+
public function testMediumDeficientNumberIsClassifiedCorrectly()
|
62
|
+
{
|
63
|
+
$this->markTestSkipped();
|
64
|
+
|
65
|
+
$this->assertEquals("deficient", getClassification(32));
|
66
|
+
}
|
67
|
+
|
68
|
+
public function testLargeDeficientNumberIsClassifiedCorrectly()
|
69
|
+
{
|
70
|
+
$this->markTestSkipped();
|
71
|
+
|
72
|
+
$this->assertEquals("deficient", getClassification(33550337));
|
73
|
+
}
|
74
|
+
|
75
|
+
public function testThatOneIsCorrectlyClassifiedAsDeficient()
|
76
|
+
{
|
77
|
+
$this->markTestSkipped();
|
78
|
+
|
79
|
+
$this->assertEquals("deficient", getClassification(1));
|
80
|
+
}
|
81
|
+
|
82
|
+
public function testThatNonNegativeIntegerIsRejected()
|
83
|
+
{
|
84
|
+
$this->markTestSkipped();
|
85
|
+
|
86
|
+
$this->expectException(InvalidArgumentException::class) ;
|
87
|
+
|
88
|
+
getClassification(0) ;
|
89
|
+
}
|
90
|
+
|
91
|
+
public function testThatNegativeIntegerIsRejected()
|
92
|
+
{
|
93
|
+
$this->markTestSkipped();
|
94
|
+
|
95
|
+
$this->expectException(InvalidArgumentException::class) ;
|
96
|
+
|
97
|
+
getClassification(-1) ;
|
98
|
+
}
|
99
|
+
}
|
@@ -2,21 +2,45 @@
|
|
2
2
|
|
3
3
|
# TEST
|
4
4
|
|
5
|
+
xpurescript=$(dirname "$BASH_SOURCE")
|
6
|
+
xpurescript=$(readlink -f "$xpurescript/..")
|
7
|
+
cd "$xpurescript"
|
8
|
+
echo "xpurescript: $xpurescript"
|
9
|
+
|
10
|
+
cache_dir="$HOME"
|
11
|
+
if [ -z "$TRAVIS" ]; then
|
12
|
+
cache_dir="$xpurescript"
|
13
|
+
fi
|
14
|
+
cache_dir="$cache_dir/.exercise_cache"
|
15
|
+
echo "cache_dir: $cache_dir"
|
16
|
+
|
5
17
|
declare -i TEST_RESULT=0
|
6
18
|
FAILED_EXERCISES=''
|
7
19
|
|
8
|
-
|
9
|
-
do
|
10
|
-
exercise_src="$exercise_dir/src"
|
11
|
-
exercise_examples_src="$exercise_dir/examples/src"
|
12
|
-
|
13
|
-
mv "$exercise_src" "$exercise_src.impl"
|
14
|
-
mv "$exercise_examples_src" "$exercise_src"
|
20
|
+
cd exercises
|
15
21
|
|
22
|
+
for exercise_dir in *
|
23
|
+
do
|
16
24
|
echo "-------------------------------------------------------"
|
17
25
|
echo "Testing $exercise_dir"
|
18
26
|
|
19
27
|
cd "$exercise_dir"
|
28
|
+
|
29
|
+
exercise_src=src
|
30
|
+
exercise_examples_src=examples/src
|
31
|
+
|
32
|
+
# Setup Travis cache
|
33
|
+
for dir in bower_components output; do
|
34
|
+
cache="$cache_dir/$exercise_dir/$dir"
|
35
|
+
|
36
|
+
mkdir -p "$cache"
|
37
|
+
ln -f -s "$cache"
|
38
|
+
echo "cache: $(ls -l "$dir")"
|
39
|
+
done
|
40
|
+
|
41
|
+
mv "$exercise_src" "$exercise_src.impl"
|
42
|
+
mv "$exercise_examples_src" "$exercise_src"
|
43
|
+
|
20
44
|
bower install
|
21
45
|
pulp test
|
22
46
|
|
@@ -27,9 +51,10 @@ do
|
|
27
51
|
fi
|
28
52
|
|
29
53
|
# be kind, rewind
|
30
|
-
cd -
|
31
54
|
mv "$exercise_src" "$exercise_examples_src"
|
32
55
|
mv "$exercise_src.impl" "$exercise_src"
|
56
|
+
|
57
|
+
cd -
|
33
58
|
done
|
34
59
|
|
35
60
|
if [ $TEST_RESULT -ne 0 ]; then
|
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"name": "meetup",
|
3
|
+
"ignore": [
|
4
|
+
"**/.*",
|
5
|
+
"node_modules",
|
6
|
+
"bower_components",
|
7
|
+
"output"
|
8
|
+
],
|
9
|
+
"dependencies": {
|
10
|
+
"purescript-prelude": "^2.5.0",
|
11
|
+
"purescript-datetime": "^2.2.0"
|
12
|
+
},
|
13
|
+
"devDependencies": {
|
14
|
+
"purescript-psci-support": "^2.0.0",
|
15
|
+
"purescript-test-unit": "^10.1.0"
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Meetup
|
2
|
+
( meetup
|
3
|
+
, Week(..)
|
4
|
+
) where
|
5
|
+
|
6
|
+
import Prelude
|
7
|
+
import Data.Array (catMaybes, filter, last, (!!))
|
8
|
+
import Data.Date (Date, Month, Weekday, Year, day, exactDate, weekday)
|
9
|
+
import Data.Enum (enumFromTo, toEnum)
|
10
|
+
import Data.Maybe (Maybe(..))
|
11
|
+
|
12
|
+
data Week = First
|
13
|
+
| Second
|
14
|
+
| Third
|
15
|
+
| Fourth
|
16
|
+
| Last
|
17
|
+
| Teenth
|
18
|
+
|
19
|
+
sat :: Week -> Array Date -> Maybe Date
|
20
|
+
sat First ds = ds !! 0
|
21
|
+
sat Second ds = ds !! 1
|
22
|
+
sat Third ds = ds !! 2
|
23
|
+
sat Fourth ds = ds !! 3
|
24
|
+
sat Last ds = last ds
|
25
|
+
sat Teenth ds = do
|
26
|
+
lot <- toEnum 13
|
27
|
+
hit <- toEnum 19
|
28
|
+
case filter (day >>> between lot hit) ds of
|
29
|
+
[e] -> pure e
|
30
|
+
_ -> Nothing
|
31
|
+
|
32
|
+
meetup :: Year -> Month -> Week -> Weekday -> Maybe Date
|
33
|
+
meetup y m w wd = enumFromTo bottom top
|
34
|
+
# map (exactDate y m)
|
35
|
+
# catMaybes
|
36
|
+
# filter (\d -> weekday d == wd)
|
37
|
+
# sat w
|