trackler 2.2.1.48 → 2.2.1.49

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/grains/canonical-data.json +1 -1
  4. data/problem-specifications/exercises/isbn-verifier/description.md +1 -1
  5. data/tracks/dart/exercises/anagram/pubspec.lock +10 -10
  6. data/tracks/dart/exercises/bob/pubspec.lock +4 -4
  7. data/tracks/dart/exercises/difference-of-squares/pubspec.lock +4 -4
  8. data/tracks/dart/exercises/gigasecond/pubspec.lock +4 -4
  9. data/tracks/dart/exercises/hamming/pubspec.lock +4 -4
  10. data/tracks/dart/exercises/hello-world/pubspec.lock +4 -4
  11. data/tracks/dart/exercises/leap/pubspec.lock +4 -4
  12. data/tracks/dart/exercises/phone-number/pubspec.lock +4 -4
  13. data/tracks/dart/exercises/raindrops/pubspec.lock +17 -5
  14. data/tracks/dart/exercises/rna-transcription/pubspec.lock +4 -4
  15. data/tracks/dart/exercises/word-count/pubspec.lock +4 -4
  16. data/tracks/dart/pubspec.lock +3 -3
  17. data/tracks/fsharp/exercises/largest-series-product/Example.fs +18 -4
  18. data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProduct.fs +1 -1
  19. data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProductTest.fs +80 -36
  20. data/tracks/fsharp/generators/Exercise.fs +1 -1
  21. data/tracks/fsharp/generators/Generators.fs +10 -0
  22. data/tracks/gnu-apl/config.json +14 -0
  23. data/tracks/gnu-apl/exercises/difference-of-squares/README.md +19 -0
  24. data/tracks/gnu-apl/exercises/difference-of-squares/difference-of-squares-example.apl +13 -0
  25. data/tracks/gnu-apl/exercises/difference-of-squares/difference-of-squares.tc +38 -0
  26. data/tracks/gnu-apl/exercises/pangram/README.md +15 -0
  27. data/tracks/gnu-apl/exercises/pangram/pangram-example.apl +14 -0
  28. data/tracks/gnu-apl/exercises/pangram/pangram.tc +40 -0
  29. data/tracks/gnu-apl/exercises/raindrops/raindrops.tc +1 -1
  30. data/tracks/java/exercises/bracket-push/.meta/version +1 -0
  31. data/tracks/java/exercises/complex-numbers/.meta/version +1 -0
  32. data/tracks/java/exercises/ocr-numbers/.meta/version +1 -0
  33. data/tracks/java/exercises/queen-attack/.meta/version +1 -0
  34. data/tracks/java/exercises/rectangles/.meta/version +1 -0
  35. data/tracks/java/exercises/robot-simulator/.meta/version +1 -0
  36. data/tracks/java/exercises/secret-handshake/.meta/version +1 -0
  37. data/tracks/java/exercises/sublist/.meta/version +1 -0
  38. data/tracks/perl6/exercises/accumulate/accumulate.t +1 -6
  39. data/tracks/perl6/exercises/all-your-base/all-your-base.t +14 -19
  40. data/tracks/perl6/exercises/allergies/Allergies.pm6 +1 -1
  41. data/tracks/perl6/exercises/allergies/Example.pm6 +1 -1
  42. data/tracks/perl6/exercises/allergies/allergies.t +25 -29
  43. data/tracks/perl6/exercises/allergies/example.yaml +11 -10
  44. data/tracks/perl6/exercises/anagram/anagram.t +14 -19
  45. data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +14 -19
  46. data/tracks/perl6/exercises/bob/bob.t +16 -23
  47. data/tracks/perl6/exercises/bob/example.yaml +1 -3
  48. data/tracks/perl6/exercises/clock/clock.t +14 -19
  49. data/tracks/perl6/exercises/flatten-array/flatten-array.t +14 -19
  50. data/tracks/perl6/exercises/grade-school/grade-school.t +1 -6
  51. data/tracks/perl6/exercises/grains/grains.t +15 -20
  52. data/tracks/perl6/exercises/hello-world/example.yaml +1 -3
  53. data/tracks/perl6/exercises/hello-world/hello-world.t +16 -23
  54. data/tracks/perl6/exercises/leap/leap.t +14 -19
  55. data/tracks/perl6/exercises/linked-list/example.yaml +59 -59
  56. data/tracks/perl6/exercises/linked-list/linked-list.t +59 -64
  57. data/tracks/perl6/exercises/luhn/luhn.t +14 -19
  58. data/tracks/perl6/exercises/phone-number/phone-number.t +14 -19
  59. data/tracks/perl6/exercises/raindrops/raindrops.t +14 -19
  60. data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +14 -19
  61. data/tracks/perl6/exercises/robot-name/robot-name.t +1 -6
  62. data/tracks/perl6/exercises/scrabble-score/scrabble-score.t +14 -19
  63. data/tracks/perl6/exercises/space-age/space-age.t +14 -19
  64. data/tracks/perl6/exercises/word-count/word-count.t +14 -19
  65. data/tracks/perl6/exercises/wordy/wordy.t +14 -19
  66. data/tracks/perl6/templates/test.mustache +19 -25
  67. data/tracks/purescript/config.json +12 -0
  68. data/tracks/purescript/exercises/sum-of-multiples/README.md +15 -0
  69. data/tracks/purescript/exercises/sum-of-multiples/bower.json +26 -0
  70. data/tracks/purescript/exercises/sum-of-multiples/examples/src/SumOfMultiples.purs +16 -0
  71. data/tracks/purescript/exercises/sum-of-multiples/src/SumOfMultiples.purs +3 -0
  72. data/tracks/purescript/exercises/sum-of-multiples/test/Main.purs +63 -0
  73. data/tracks/python/README.md +5 -1
  74. data/tracks/python/config.json +52 -9
  75. data/tracks/python/exercises/allergies/allergies_test.py +7 -7
  76. data/tracks/python/exercises/allergies/example.py +1 -1
  77. data/tracks/python/exercises/binary-search/binary_search_test.py +8 -5
  78. data/tracks/python/exercises/binary/binary_test.py +8 -4
  79. data/tracks/python/exercises/book-store/example.py +1 -1
  80. data/tracks/python/exercises/clock/clock.py +3 -0
  81. data/tracks/python/exercises/clock/clock_test.py +16 -16
  82. data/tracks/python/exercises/clock/example.py +1 -1
  83. data/tracks/python/exercises/list-ops/example.py +10 -29
  84. data/tracks/python/exercises/list-ops/list_ops.py +8 -12
  85. data/tracks/python/exercises/list-ops/list_ops_test.py +55 -86
  86. data/tracks/python/exercises/meetup/meetup_test.py +2 -2
  87. data/tracks/python/exercises/minesweeper/minesweeper_test.py +6 -3
  88. data/tracks/python/exercises/ocr-numbers/ocr_numbers_test.py +11 -8
  89. data/tracks/python/exercises/pangram/pangram_test.py +25 -16
  90. data/tracks/python/exercises/point-mutations/point_mutations.py +1 -1
  91. data/tracks/python/exercises/pythagorean-triplet/pythagorean_triplet_test.py +2 -1
  92. data/tracks/python/exercises/saddle-points/saddle_points_test.py +2 -1
  93. data/tracks/python/exercises/simple-cipher/simple_cipher_test.py +4 -2
  94. data/tracks/python/exercises/triangle/triangle_test.py +10 -5
  95. data/tracks/python/exercises/wordy/wordy_test.py +8 -5
  96. data/tracks/python/exercises/zipper/README.md +43 -0
  97. data/tracks/python/exercises/zipper/example.py +41 -0
  98. data/tracks/python/exercises/zipper/zipper.py +28 -0
  99. data/tracks/python/exercises/zipper/zipper_test.py +82 -0
  100. data/tracks/racket/.travis.yml +1 -1
  101. data/tracks/racket/config.json +14 -0
  102. data/tracks/racket/exercises/meetup/README.md +54 -0
  103. data/tracks/racket/exercises/meetup/example.rkt +45 -0
  104. data/tracks/racket/exercises/meetup/meetup-test.rkt +39 -0
  105. data/tracks/racket/exercises/meetup/meetup.rkt +3 -0
  106. metadata +29 -2
@@ -68,8 +68,10 @@ class CipherTest(unittest.TestCase):
68
68
  'All items in the key must be chars and lowercase!')
69
69
 
70
70
  def test_cipher_wrong_key(self):
71
- self.assertRaises(ValueError, Cipher, 'a1cde')
72
- self.assertRaises(ValueError, Cipher, 'aBcde')
71
+ with self.assertRaises(ValueError):
72
+ Cipher('a1cde')
73
+ with self.assertRaises(ValueError):
74
+ Cipher('aBcde')
73
75
 
74
76
 
75
77
  if __name__ == '__main__':
@@ -34,19 +34,24 @@ class TriangleTests(unittest.TestCase):
34
34
  self.assertEqual(Triangle(0.4, 0.6, 0.3).kind(), "scalene")
35
35
 
36
36
  def test_triangles_with_no_size_are_illegal(self):
37
- self.assertRaises(TriangleError, Triangle, 0, 0, 0)
37
+ with self.assertRaises(TriangleError):
38
+ Triangle(0, 0, 0)
38
39
 
39
40
  def test_triangles_with_negative_sides_are_illegal(self):
40
- self.assertRaises(TriangleError, Triangle, 3, 4, -5)
41
+ with self.assertRaises(TriangleError):
42
+ Triangle(3, 4, -5)
41
43
 
42
44
  def test_triangles_violating_triangle_inequality_are_illegal(self):
43
- self.assertRaises(TriangleError, Triangle, 1, 1, 3)
45
+ with self.assertRaises(TriangleError):
46
+ Triangle(1, 1, 3)
44
47
 
45
48
  def test_triangles_violating_triangle_inequality_are_illegal_2(self):
46
- self.assertRaises(TriangleError, Triangle, 2, 4, 2)
49
+ with self.assertRaises(TriangleError):
50
+ Triangle(2, 4, 2)
47
51
 
48
52
  def test_triangles_violating_triangle_inequality_are_illegal_3(self):
49
- self.assertRaises(TriangleError, Triangle, 7, 3, 2)
53
+ with self.assertRaises(TriangleError):
54
+ Triangle(7, 3, 2)
50
55
 
51
56
 
52
57
  if __name__ == '__main__':
@@ -49,17 +49,20 @@ class WordyTest(unittest.TestCase):
49
49
  calculate("What is -12000 divided by 25 divided by -30?"), 16)
50
50
 
51
51
  def test_invalid_operation(self):
52
- self.assertRaises(ValueError, calculate, "What is 4 xor 7?")
52
+ with self.assertRaises(ValueError):
53
+ calculate("What is 4 xor 7?")
53
54
 
54
55
  def test_missing_operation(self):
55
- self.assertRaises(ValueError, calculate, "What is 2 2 minus 3?")
56
+ with self.assertRaises(ValueError):
57
+ calculate("What is 2 2 minus 3?")
56
58
 
57
59
  def test_missing_number(self):
58
- self.assertRaises(ValueError, calculate,
59
- "What is 7 plus multiplied by -2?")
60
+ with self.assertRaises(ValueError):
61
+ calculate("What is 7 plus multiplied by -2?")
60
62
 
61
63
  def test_irrelevant_question(self):
62
- self.assertRaises(ValueError, calculate, "Which is greater, 3 or 2?")
64
+ with self.assertRaises(ValueError):
65
+ calculate("Which is greater, 3 or 2?")
63
66
 
64
67
 
65
68
  if __name__ == '__main__':
@@ -0,0 +1,43 @@
1
+ # Zipper
2
+
3
+ Creating a zipper for a binary tree.
4
+
5
+ [Zippers](https://en.wikipedia.org/wiki/Zipper_%28data_structure%29) are
6
+ a purely functional way of navigating within a data structure and
7
+ manipulating it. They essentially contain a data structure and a
8
+ pointer into that data structure (called the focus).
9
+
10
+ For example given a rose tree (where each node contains a value and a
11
+ list of child nodes) a zipper might support these operations:
12
+
13
+ - `from_tree` (get a zipper out of a rose tree, the focus is on the root node)
14
+ - `to_tree` (get the rose tree out of the zipper)
15
+ - `value` (get the value of the focus node)
16
+ - `prev` (move the focus to the previous child of the same parent,
17
+ returns a new zipper)
18
+ - `next` (move the focus to the next child of the same parent, returns a
19
+ new zipper)
20
+ - `up` (move the focus to the parent, returns a new zipper)
21
+ - `set_value` (set the value of the focus node, returns a new zipper)
22
+ - `insert_before` (insert a new subtree before the focus node, it
23
+ becomes the `prev` of the focus node, returns a new zipper)
24
+ - `insert_after` (insert a new subtree after the focus node, it becomes
25
+ the `next` of the focus node, returns a new zipper)
26
+ - `delete` (removes the focus node and all subtrees, focus moves to the
27
+ `next` node if possible otherwise to the `prev` node if possible,
28
+ otherwise to the parent node, returns a new zipper)
29
+
30
+ ### Submitting Exercises
31
+
32
+ Note that, when trying to submit an exercise, make sure the solution is in the `exercism/python/<exerciseName>` directory.
33
+
34
+ For example, if you're submitting `bob.py` for the Bob exercise, the submit command would be something like `exercism submit <path_to_exercism_dir>/python/bob/bob.py`.
35
+
36
+
37
+ For more detailed information about running tests, code style and linting,
38
+ please see the [help page](http://exercism.io/languages/python).
39
+
40
+
41
+ ## Submitting Incomplete Solutions
42
+
43
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,41 @@
1
+ class Zipper(object):
2
+ @staticmethod
3
+ def from_tree(tree):
4
+ return Zipper(dict(tree), [])
5
+
6
+ def __init__(self, tree, ancestors):
7
+ self.tree = tree
8
+ self.ancestors = ancestors
9
+
10
+ def value(self):
11
+ return self.tree['value']
12
+
13
+ def set_value(self, value):
14
+ self.tree['value'] = value
15
+ return self
16
+
17
+ def left(self):
18
+ if self.tree['left'] is None:
19
+ return None
20
+ return Zipper(self.tree['left'], self.ancestors + [self.tree])
21
+
22
+ def set_left(self, tree):
23
+ self.tree['left'] = tree
24
+ return self
25
+
26
+ def right(self):
27
+ if self.tree['right'] is None:
28
+ return None
29
+ return Zipper(self.tree['right'], self.ancestors + [self.tree])
30
+
31
+ def set_right(self, tree):
32
+ self.tree['right'] = tree
33
+ return self
34
+
35
+ def up(self):
36
+ return Zipper(self.ancestors[-1], self.ancestors[:-1])
37
+
38
+ def to_tree(self):
39
+ if any(self.ancestors):
40
+ return self.ancestors[0]
41
+ return self.tree
@@ -0,0 +1,28 @@
1
+ class Zipper(object):
2
+ @staticmethod
3
+ def from_tree(tree):
4
+ pass
5
+
6
+ def value(self):
7
+ pass
8
+
9
+ def set_value(self):
10
+ pass
11
+
12
+ def left(self):
13
+ pass
14
+
15
+ def set_left(self):
16
+ pass
17
+
18
+ def right(self):
19
+ pass
20
+
21
+ def set_right(self):
22
+ pass
23
+
24
+ def up(self):
25
+ pass
26
+
27
+ def to_tree(self):
28
+ pass
@@ -0,0 +1,82 @@
1
+ import unittest
2
+
3
+ from zipper import Zipper
4
+
5
+ # Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0
6
+
7
+
8
+ def bt(value, left, right):
9
+ return {
10
+ 'value': value,
11
+ 'left': left,
12
+ 'right': right
13
+ }
14
+
15
+
16
+ def leaf(value):
17
+ return bt(value, None, None)
18
+
19
+
20
+ EMPTY_TREE = None
21
+
22
+
23
+ def create_trees():
24
+ t1 = bt(1, bt(2, EMPTY_TREE, leaf(3)), leaf(4))
25
+ t2 = bt(1, bt(5, EMPTY_TREE, leaf(3)), leaf(4))
26
+ t3 = bt(1, bt(2, leaf(5), leaf(3)), leaf(4))
27
+ t4 = bt(1, leaf(2), leaf(4))
28
+ return (t1, t2, t3, t4)
29
+
30
+
31
+ class ZipperTest(unittest.TestCase):
32
+ def test_data_is_retained(self):
33
+ t1, _, _, _ = create_trees()
34
+ zipper = Zipper.from_tree(t1)
35
+ tree = zipper.to_tree()
36
+ self.assertEqual(tree, t1)
37
+
38
+ def test_left_and_right_value(self):
39
+ t1, _, _, _ = create_trees()
40
+ zipper = Zipper.from_tree(t1)
41
+ self.assertEqual(zipper.left().right().value(), 3)
42
+
43
+ def test_dead_end(self):
44
+ t1, _, _, _ = create_trees()
45
+ zipper = Zipper.from_tree(t1)
46
+ self.assertIsNone(zipper.left().left())
47
+
48
+ def test_tree_from_deep_focus(self):
49
+ t1, _, _, _ = create_trees()
50
+ zipper = Zipper.from_tree(t1)
51
+ self.assertEqual(zipper.left().right().to_tree(), t1)
52
+
53
+ def test_set_value(self):
54
+ t1, t2, _, _ = create_trees()
55
+ zipper = Zipper.from_tree(t1)
56
+ updatedZipper = zipper.left().set_value(5)
57
+ tree = updatedZipper.to_tree()
58
+ self.assertEqual(tree, t2)
59
+
60
+ def test_set_left_with_value(self):
61
+ t1, _, t3, _ = create_trees()
62
+ zipper = Zipper.from_tree(t1)
63
+ updatedZipper = zipper.left().set_left(leaf(5))
64
+ tree = updatedZipper.to_tree()
65
+ self.assertEqual(tree, t3)
66
+
67
+ def test_set_right_to_none(self):
68
+ t1, _, _, t4 = create_trees()
69
+ zipper = Zipper.from_tree(t1)
70
+ updatedZipper = zipper.left().set_right(None)
71
+ tree = updatedZipper.to_tree()
72
+ self.assertEqual(tree, t4)
73
+
74
+ def test_different_paths_to_same_zipper(self):
75
+ t1, _, _, _ = create_trees()
76
+ zipper = Zipper.from_tree(t1)
77
+ self.assertEqual(zipper.left().up().right().to_tree(),
78
+ zipper.right().to_tree())
79
+
80
+
81
+ if __name__ == '__main__':
82
+ unittest.main()
@@ -5,7 +5,7 @@ env:
5
5
  global:
6
6
  - RACKET_DIR=~/racket
7
7
  matrix:
8
- - RACKET_VERSION=6.3 RACKET_MINIMAL=1
8
+ - RACKET_VERSION=6.6 RACKET_MINIMAL=1
9
9
  before_install:
10
10
  - git clone https://github.com/zenspider/travis-racket.git
11
11
  - cd travis-racket
@@ -113,6 +113,20 @@
113
113
 
114
114
  ]
115
115
  },
116
+ {
117
+ "uuid": "d330a93f-063f-0d80-f35b-02cc2f9da754e0be296",
118
+ "slug": "meetup",
119
+ "core": false,
120
+ "unlocked_by": null,
121
+ "difficulty": 1,
122
+ "topics": [
123
+ "strings",
124
+ "conditionals",
125
+ "dates",
126
+ "parsing",
127
+ "pattern_recognition"
128
+ ]
129
+ },
116
130
  {
117
131
  "uuid": "67b41645-7a02-4c45-af55-86401db69eee",
118
132
  "slug": "anagram",
@@ -0,0 +1,54 @@
1
+ # Meetup
2
+
3
+ Calculate the date of meetups.
4
+
5
+ Typically meetups happen on the same day of the week. In this exercise, you will take
6
+ a description of a meetup date, and return the actual meetup date.
7
+
8
+ Examples of general descriptions are:
9
+
10
+ - the first Monday of January 2017
11
+ - the third Tuesday of January 2017
12
+ - the Wednesteenth of January 2017
13
+ - the last Thursday of January 2017
14
+
15
+ Note that "Monteenth", "Tuesteenth", etc are all made up words. There
16
+ was a meetup whose members realized that there are exactly 7 numbered days in a month that
17
+ end in '-teenth'. Therefore, one is guaranteed that each day of the week
18
+ (Monday, Tuesday, ...) will have exactly one date that is named with '-teenth'
19
+ in every month.
20
+
21
+ Given examples of a meetup dates, each containing a month, day, year, and descriptor
22
+ (first, second, teenth, etc), calculate the date of the actual meetup.
23
+ For example, if given "First Monday of January 2017", the correct meetup date is 2017/1/2
24
+
25
+ * * * *
26
+
27
+ For installation and learning resources, refer to the
28
+ [exercism Racket page](http://exercism.io/languages/racket).
29
+
30
+ You can run the provided tests through DrRacket, or via the command line.
31
+
32
+ To run the test through DrRacket, simply open the test file and click the 'Run' button in the upper right.
33
+
34
+ To run the test from the command line, simply run the test from the exercise directory. For example, if the test suite is called `hello-world-test.rkt`, you can run the following command:
35
+
36
+ ```
37
+ raco test hello-world-test.rkt
38
+ ```
39
+
40
+ which will display the following:
41
+
42
+ ```
43
+ raco test: (submod "hello-world-test.rkt" test)
44
+ 2 success(es) 0 failure(s) 0 error(s) 2 test(s) run
45
+ 0
46
+ 2 tests passed
47
+ ```
48
+
49
+ ## Source
50
+
51
+ Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month [https://twitter.com/copiousfreetime](https://twitter.com/copiousfreetime)
52
+
53
+ ## Submitting Incomplete Solutions
54
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,45 @@
1
+ #lang racket
2
+
3
+ (require racket/date)
4
+
5
+ (define (leap-year? year)
6
+ (or (and (zero? (modulo year 4))
7
+ (not (zero? (modulo year 100))))
8
+ (zero? (modulo year 400))))
9
+
10
+ (define (days-in-month year month)
11
+ (case month
12
+ [(1 3 5 7 8 10 12) 31]
13
+ [(4 6 9 11) 30]
14
+ [(2) (if (leap-year? year) 29 28)]))
15
+
16
+ (define (make-date year month day)
17
+ (seconds->date (find-seconds 0 0 0 day month year #f) #f))
18
+
19
+ (define (meetup-day year month weekday week)
20
+ (let ([first-of-week
21
+ (case week
22
+ [(first) 1]
23
+ [(second) 8]
24
+ [(teenth) 13]
25
+ [(third) 15]
26
+ [(fourth) 22]
27
+ [(last) (- (days-in-month year month) 6)]
28
+ [else (raise-argument-error 'meetup-day "week" 3 year month weekday week)])]
29
+ [weekday
30
+ (case weekday
31
+ [(Sunday) 0]
32
+ [(Monday) 1]
33
+ [(Tuesday) 2]
34
+ [(Wednesday) 3]
35
+ [(Thursday) 4]
36
+ [(Friday) 5]
37
+ [(Saturday) 6]
38
+ [else (raise-argument-error 'meetup-day "weekday" 3 year month weekday week)])])
39
+ (make-date year month
40
+ (+ first-of-week
41
+ (modulo
42
+ (- weekday
43
+ (date-week-day (make-date year month first-of-week))) 7)))))
44
+
45
+ (provide meetup-day)
@@ -0,0 +1,39 @@
1
+ #lang racket
2
+
3
+ (module+ test
4
+ (require rackunit rackunit/text-ui)
5
+ (require racket/date)
6
+ (require "meetup.rkt")
7
+
8
+ (define (make-date year month day)
9
+ (seconds->date (find-seconds 0 0 0 day month year #f) #f))
10
+
11
+ (define suite
12
+ (test-suite
13
+ "Tests for the meetup exercise"
14
+
15
+ (check-equal? (meetup-day 2013 5 'Monday 'teenth)
16
+ (make-date 2013 5 13))
17
+
18
+ (check-equal? (meetup-day 2013 2 'Saturday 'teenth)
19
+ (make-date 2013 2 16))
20
+
21
+ (check-equal? (meetup-day 2013 5 'Tuesday 'first)
22
+ (make-date 2013 5 7))
23
+
24
+ (check-equal? (meetup-day 2013 4 'Monday 'second)
25
+ (make-date 2013 4 8))
26
+
27
+ (check-equal? (meetup-day 2013 9 'Thursday 'third)
28
+ (make-date 2013 9 19))
29
+
30
+ (check-equal? (meetup-day 2013 3 'Sunday 'fourth)
31
+ (make-date 2013 3 24))
32
+
33
+ (check-equal? (meetup-day 2013 10 'Thursday 'last)
34
+ (make-date 2013 10 31))
35
+
36
+ (check-equal? (meetup-day 2012 2 'Wednesday 'last)
37
+ (make-date 2012 2 29))))
38
+
39
+ (run-tests suite))