trackler 2.2.1.49 → 2.2.1.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/bin/verify-configs +1 -1
  3. data/lib/trackler/version.rb +1 -1
  4. data/problem-specifications/exercises/kindergarten-garden/canonical-data.json +0 -37
  5. data/tracks/c/exercises/allergies/test/test_allergies.c +41 -41
  6. data/tracks/common-lisp/config.json +266 -252
  7. data/tracks/common-lisp/config/maintainers.json +23 -23
  8. data/tracks/common-lisp/exercises/allergies/README.md +0 -1
  9. data/tracks/common-lisp/exercises/atbash-cipher/README.md +2 -1
  10. data/tracks/common-lisp/exercises/beer-song/README.md +1 -1
  11. data/tracks/common-lisp/exercises/binary/README.md +2 -0
  12. data/tracks/common-lisp/exercises/collatz-conjecture/README.md +4 -8
  13. data/tracks/common-lisp/exercises/crypto-square/README.md +4 -4
  14. data/tracks/common-lisp/exercises/etl/README.md +2 -0
  15. data/tracks/common-lisp/exercises/grade-school/README.md +0 -1
  16. data/tracks/common-lisp/exercises/grains/README.md +0 -1
  17. data/tracks/common-lisp/exercises/leap/README.md +1 -1
  18. data/tracks/common-lisp/exercises/meetup/README.md +1 -2
  19. data/tracks/common-lisp/exercises/nucleotide-count/README.md +8 -22
  20. data/tracks/common-lisp/exercises/pascals-triangle/README.md +1 -1
  21. data/tracks/common-lisp/exercises/perfect-numbers/README.md +3 -4
  22. data/tracks/common-lisp/exercises/phone-number/README.md +3 -2
  23. data/tracks/common-lisp/exercises/roman-numerals/README.md +1 -1
  24. data/tracks/common-lisp/exercises/scrabble-score/README.md +3 -1
  25. data/tracks/common-lisp/exercises/space-age/README.md +2 -1
  26. data/tracks/common-lisp/exercises/sublist/README.md +65 -0
  27. data/tracks/common-lisp/exercises/sublist/example.lisp +24 -0
  28. data/tracks/common-lisp/exercises/sublist/sublist-test.lisp +87 -0
  29. data/tracks/common-lisp/exercises/sublist/sublist.lisp +8 -0
  30. data/tracks/common-lisp/exercises/triangle/README.md +9 -6
  31. data/tracks/common-lisp/exercises/trinary/README.md +1 -1
  32. data/tracks/common-lisp/exercises/word-count/README.md +1 -2
  33. data/tracks/ecmascript/config.json +30 -0
  34. data/tracks/ecmascript/exercises/bowling/README.md +80 -0
  35. data/tracks/ecmascript/exercises/bowling/bowling.spec.js +159 -0
  36. data/tracks/ecmascript/exercises/bowling/example.js +67 -0
  37. data/tracks/ecmascript/exercises/bowling/package.json +71 -0
  38. data/tracks/ecmascript/exercises/two-fer/README.md +47 -0
  39. data/tracks/ecmascript/exercises/two-fer/example.js +4 -0
  40. data/tracks/ecmascript/exercises/two-fer/package.json +69 -0
  41. data/tracks/ecmascript/exercises/two-fer/two-fer.spec.js +18 -0
  42. data/tracks/fsharp/exercises/pascals-triangle/Example.fs +12 -8
  43. data/tracks/fsharp/exercises/pascals-triangle/PascalsTriangle.fs +2 -2
  44. data/tracks/fsharp/exercises/pascals-triangle/PascalsTriangleTest.fs +15 -12
  45. data/tracks/fsharp/generators/Generators.fs +19 -0
  46. data/tracks/fsharp/generators/Templates/_AssertThrows.liquid +1 -0
  47. data/tracks/java/docs/ABOUT.md +13 -31
  48. data/tracks/java/exercises/bracket-push/.meta/version +1 -1
  49. data/tracks/java/exercises/bracket-push/src/test/java/BracketCheckerTest.java +7 -1
  50. data/tracks/java/exercises/collatz-conjecture/.meta/version +1 -1
  51. data/tracks/java/exercises/etl/README.md +1 -1
  52. data/tracks/java/exercises/ocr-numbers/README.md +1 -1
  53. data/tracks/java/exercises/pascals-triangle/README.md +1 -1
  54. data/tracks/java/exercises/perfect-numbers/.meta/version +1 -1
  55. data/tracks/java/exercises/rna-transcription/README.md +1 -1
  56. data/tracks/java/exercises/secret-handshake/.meta/version +1 -1
  57. data/tracks/java/exercises/secret-handshake/src/test/java/HandshakeCalculatorTest.java +1 -9
  58. data/tracks/java/scripts/canonical_data_check.sh +104 -0
  59. data/tracks/javascript/exercises/twelve-days/example.js +23 -25
  60. data/tracks/julia/.travis.yml +1 -0
  61. data/tracks/kotlin/exercises/all-your-base/.meta/version +1 -0
  62. data/tracks/kotlin/exercises/all-your-base/src/test/kotlin/BaseConverterTest.kt +0 -3
  63. data/tracks/kotlin/exercises/change/.meta/version +1 -0
  64. data/tracks/kotlin/exercises/change/src/test/kotlin/ChangeCalculatorTest.kt +0 -3
  65. data/tracks/kotlin/exercises/clock/.meta/version +1 -0
  66. data/tracks/kotlin/exercises/clock/src/test/kotlin/ClockAddTest.kt +1 -4
  67. data/tracks/kotlin/exercises/clock/src/test/kotlin/ClockCreationTest.kt +1 -4
  68. data/tracks/kotlin/exercises/clock/src/test/kotlin/ClockEqualTest.kt +1 -4
  69. data/tracks/kotlin/exercises/collatz-conjecture/.meta/version +1 -0
  70. data/tracks/kotlin/exercises/collatz-conjecture/src/test/kotlin/CollatzCalculatorTest.kt +0 -3
  71. data/tracks/kotlin/exercises/complex-numbers/.meta/version +1 -0
  72. data/tracks/kotlin/exercises/complex-numbers/src/test/kotlin/ComplexNumberTest.kt +0 -3
  73. data/tracks/kotlin/exercises/diamond/.meta/version +1 -0
  74. data/tracks/kotlin/exercises/diamond/src/test/kotlin/DiamondPrinterTest.kt +0 -3
  75. data/tracks/kotlin/exercises/etl/README.md +1 -1
  76. data/tracks/kotlin/exercises/forth/.meta/version +1 -0
  77. data/tracks/kotlin/exercises/forth/src/test/kotlin/ForthEvaluatorTest.kt +0 -3
  78. data/tracks/kotlin/exercises/grains/.meta/version +1 -0
  79. data/tracks/kotlin/exercises/grains/src/test/kotlin/BoardTest.kt +0 -3
  80. data/tracks/kotlin/exercises/hamming/.meta/version +1 -0
  81. data/tracks/kotlin/exercises/hamming/src/test/kotlin/HammingTest.kt +0 -3
  82. data/tracks/kotlin/exercises/list-ops/.meta/version +1 -0
  83. data/tracks/kotlin/exercises/list-ops/src/test/kotlin/ListExtensionsTest.kt +0 -3
  84. data/tracks/kotlin/exercises/meetup/.meta/version +1 -0
  85. data/tracks/kotlin/exercises/meetup/src/test/kotlin/MeetupTest.kt +0 -3
  86. data/tracks/kotlin/exercises/minesweeper/.meta/version +1 -0
  87. data/tracks/kotlin/exercises/minesweeper/src/test/kotlin/MinesweeperBoardTest.kt +0 -3
  88. data/tracks/kotlin/exercises/pangram/.meta/version +1 -0
  89. data/tracks/kotlin/exercises/pangram/src/test/kotlin/PangramTest.kt +0 -3
  90. data/tracks/kotlin/exercises/pascals-triangle/README.md +1 -1
  91. data/tracks/kotlin/exercises/prime-factors/.meta/version +1 -0
  92. data/tracks/kotlin/exercises/prime-factors/src/test/kotlin/PrimeFactorCalculatorTest.kt +0 -3
  93. data/tracks/kotlin/exercises/rna-transcription/.meta/version +1 -0
  94. data/tracks/kotlin/exercises/rna-transcription/README.md +1 -1
  95. data/tracks/kotlin/exercises/rna-transcription/src/test/kotlin/RnaTranscriptionTest.kt +0 -3
  96. data/tracks/kotlin/exercises/robot-simulator/.meta/version +1 -0
  97. data/tracks/kotlin/exercises/robot-simulator/src/test/kotlin/RobotTest.kt +0 -3
  98. data/tracks/kotlin/exercises/rotational-cipher/.meta/version +1 -0
  99. data/tracks/kotlin/exercises/rotational-cipher/src/test/kotlin/RotationalCipherTest.kt +0 -3
  100. data/tracks/kotlin/exercises/saddle-points/.meta/version +1 -0
  101. data/tracks/kotlin/exercises/saddle-points/src/test/kotlin/MatrixTest.kt +0 -3
  102. data/tracks/kotlin/exercises/say/.meta/version +1 -0
  103. data/tracks/kotlin/exercises/say/src/test/kotlin/NumberSpellerTest.kt +0 -3
  104. data/tracks/kotlin/exercises/secret-handshake/.meta/version +1 -0
  105. data/tracks/kotlin/exercises/secret-handshake/src/test/kotlin/HandshakeCalculatorTest.kt +0 -3
  106. data/tracks/kotlin/exercises/spiral-matrix/.meta/version +1 -0
  107. data/tracks/kotlin/exercises/spiral-matrix/src/test/kotlin/SpiralMatrixTest.kt +0 -3
  108. data/tracks/kotlin/exercises/sublist/.meta/version +1 -0
  109. data/tracks/kotlin/exercises/sublist/src/test/kotlin/SublistTest.kt +0 -3
  110. data/tracks/kotlin/scripts/canonical_data_check.sh +104 -0
  111. data/tracks/perl6/exercises/accumulate/accumulate.t +2 -3
  112. data/tracks/perl6/exercises/all-your-base/all-your-base.t +17 -18
  113. data/tracks/perl6/exercises/allergies/allergies.t +17 -18
  114. data/tracks/perl6/exercises/anagram/anagram.t +17 -18
  115. data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +17 -18
  116. data/tracks/perl6/exercises/bob/bob.t +20 -22
  117. data/tracks/perl6/exercises/bob/example.yaml +1 -2
  118. data/tracks/perl6/exercises/clock/clock.t +17 -18
  119. data/tracks/perl6/exercises/flatten-array/flatten-array.t +17 -18
  120. data/tracks/perl6/exercises/grade-school/grade-school.t +2 -3
  121. data/tracks/perl6/exercises/grains/grains.t +17 -18
  122. data/tracks/perl6/exercises/hello-world/example.yaml +1 -2
  123. data/tracks/perl6/exercises/hello-world/hello-world.t +20 -22
  124. data/tracks/perl6/exercises/leap/leap.t +17 -18
  125. data/tracks/perl6/exercises/linked-list/linked-list.t +2 -3
  126. data/tracks/perl6/exercises/luhn/luhn.t +17 -18
  127. data/tracks/perl6/exercises/phone-number/phone-number.t +17 -18
  128. data/tracks/perl6/exercises/raindrops/raindrops.t +17 -18
  129. data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +17 -18
  130. data/tracks/perl6/exercises/robot-name/robot-name.t +2 -3
  131. data/tracks/perl6/exercises/scrabble-score/scrabble-score.t +17 -18
  132. data/tracks/perl6/exercises/space-age/space-age.t +17 -18
  133. data/tracks/perl6/exercises/word-count/word-count.t +17 -18
  134. data/tracks/perl6/exercises/wordy/wordy.t +17 -18
  135. data/tracks/perl6/templates/test.mustache +9 -10
  136. data/tracks/purescript/config.json +11 -0
  137. data/tracks/purescript/exercises/rna-transcription/README.md +25 -0
  138. data/tracks/purescript/exercises/rna-transcription/bower.json +26 -0
  139. data/tracks/purescript/exercises/rna-transcription/examples/src/RNATranscription.purs +18 -0
  140. data/tracks/purescript/exercises/rna-transcription/src/RNATranscription.purs +3 -0
  141. data/tracks/purescript/exercises/rna-transcription/test/Main.purs +48 -0
  142. data/tracks/python/exercises/variable-length-quantity/example.py +6 -6
  143. data/tracks/python/exercises/variable-length-quantity/variable_length_quantity.py +2 -2
  144. data/tracks/ruby/config.json +6 -0
  145. data/tracks/ruby/exercises/complex-numbers/.meta/.version +1 -0
  146. data/tracks/ruby/exercises/complex-numbers/.meta/generator/complex_numbers_case.rb +44 -0
  147. data/tracks/ruby/exercises/complex-numbers/.meta/solutions/complex_numbers.rb +49 -0
  148. data/tracks/ruby/exercises/complex-numbers/README.md +64 -0
  149. data/tracks/ruby/exercises/complex-numbers/complex_numbers_test.rb +207 -0
  150. data/tracks/ruby/exercises/crypto-square/.meta/.version +1 -0
  151. data/tracks/ruby/exercises/crypto-square/.meta/generator/crypto_square_case.rb +19 -0
  152. data/tracks/ruby/exercises/crypto-square/.meta/solutions/crypto_square.rb +20 -15
  153. data/tracks/ruby/exercises/crypto-square/README.md +10 -8
  154. data/tracks/ruby/exercises/crypto-square/crypto_square_test.rb +45 -81
  155. data/tracks/ruby/exercises/flatten-array/.meta/.version +1 -0
  156. data/tracks/ruby/exercises/flatten-array/.meta/generator/flatten_array_case.rb +11 -0
  157. data/tracks/ruby/exercises/flatten-array/.meta/solutions/flatten_array.rb +5 -2
  158. data/tracks/ruby/exercises/flatten-array/flatten_array_test.rb +32 -7
  159. data/tracks/ruby/exercises/hamming/hamming_test.rb +3 -3
  160. data/tracks/ruby/exercises/isogram/isogram_test.rb +4 -4
  161. data/tracks/ruby/exercises/leap/leap_test.rb +2 -2
  162. data/tracks/ruby/exercises/pig-latin/.meta/.version +1 -1
  163. data/tracks/ruby/exercises/pig-latin/.meta/solutions/pig_latin.rb +2 -2
  164. data/tracks/ruby/exercises/pig-latin/pig_latin_test.rb +17 -7
  165. data/tracks/ruby/exercises/queen-attack/.meta/generator/queen_attack_case.rb +1 -1
  166. data/tracks/ruby/exercises/queen-attack/queen_attack_test.rb +7 -7
  167. data/tracks/ruby/exercises/sum-of-multiples/.meta/.version +1 -1
  168. data/tracks/ruby/exercises/sum-of-multiples/.meta/solutions/sum_of_multiples.rb +1 -1
  169. data/tracks/ruby/exercises/sum-of-multiples/sum_of_multiples_test.rb +7 -2
  170. metadata +53 -2
@@ -0,0 +1,24 @@
1
+ (defpackage #:sublist
2
+ (:use #:common-lisp)
3
+ (:export #:sublist))
4
+
5
+ (in-package #:sublist)
6
+
7
+ (defun is-prefix-of (xs ys)
8
+ (cond ((null xs) T)
9
+ ((null ys) NIL)
10
+ ((equal (car xs) (car ys)) (is-prefix-of (cdr xs) (cdr ys)))
11
+ (T NIL)))
12
+
13
+ (defun sublist-of (xs ys)
14
+ (if (and xs (null ys))
15
+ nil
16
+ (or (is-prefix-of xs ys) (sublist-of xs (cdr ys)))))
17
+
18
+ (defun sublist (xs ys)
19
+ (let ((sub (sublist-of xs ys))
20
+ (super (sublist-of ys xs)))
21
+ (cond ((and sub super) "equal")
22
+ (sub "sublist")
23
+ (super "superlist")
24
+ (T "unequal"))))
@@ -0,0 +1,87 @@
1
+ (ql:quickload "lisp-unit")
2
+ #-xlisp-test (load "sublist")
3
+
4
+ (defpackage #:sublist-test
5
+ (:use #:common-lisp #:lisp-unit))
6
+
7
+ (in-package #:sublist-test)
8
+
9
+
10
+ ;; Equal lists tests:
11
+ (define-test empty-lists
12
+ (assert-equal "equal" (sublist:sublist (list)
13
+ (list))))
14
+
15
+ (define-test list-equals-itself
16
+ (assert-equal "equal" (sublist:sublist (list 1 2 3)
17
+ (list 1 2 3))))
18
+
19
+
20
+ ;; Unequal lists tests:
21
+ (define-test different-lists
22
+ (assert-equal "unequal" (sublist:sublist (list 1 2 3)
23
+ (list 2 3 4))))
24
+
25
+ (define-test first-list-missing-element-from-second-list
26
+ (assert-equal "unequal" (sublist:sublist (list 1 3)
27
+ (list 1 2 3))))
28
+
29
+ (define-test second-list-missing-element-from-first-list
30
+ (assert-equal "unequal" (sublist:sublist (list 1 2 3)
31
+ (list 1 3))))
32
+
33
+ (define-test order-matters-to-a-lists
34
+ (assert-equal "unequal" (sublist:sublist (list 1 2 3)
35
+ (list 3 2 1))))
36
+
37
+ (define-test same-digits-different-numbers
38
+ (assert-equal "unequal" (sublist:sublist (list 1 0 1)
39
+ (list 10 1))))
40
+
41
+ ;; Sublist lists tests:
42
+ (define-test empty-list-within-non-empty-list
43
+ (assert-equal "sublist" (sublist:sublist (list)
44
+ (list 1 2 3))))
45
+
46
+ (define-test false-start
47
+ (assert-equal "sublist" (sublist:sublist (list 1 2 5)
48
+ (list 0 1 2 3 1 2 5 6))))
49
+
50
+ (define-test consecutive
51
+ (assert-equal "sublist" (sublist:sublist (list 1 1 2)
52
+ (list 0 1 1 1 2 1 2))))
53
+
54
+ (define-test sublist-at-start
55
+ (assert-equal "sublist" (sublist:sublist (list 0 1 2)
56
+ (list 0 1 2 3 4 5))))
57
+
58
+ (define-test sublist-in-middle
59
+ (assert-equal "sublist" (sublist:sublist (list 2 3 4)
60
+ (list 0 1 2 3 4 5))))
61
+
62
+ (define-test sublist-at-end
63
+ (assert-equal "sublist" (sublist:sublist (list 3 4 5)
64
+ (list 0 1 2 3 4 5))))
65
+
66
+
67
+ ;; Superlist lists tests:
68
+ (define-test not-empty-list-contains-empty-list
69
+ (assert-equal "superlist" (sublist:sublist (list 1 2 3)
70
+ (list))))
71
+
72
+ (define-test at-start-of-superlist
73
+ (assert-equal "superlist" (sublist:sublist (list 0 1 2 3 4 5)
74
+ (list 0 1 2))))
75
+
76
+ (define-test in-middle-of-superlist
77
+ (assert-equal "superlist" (sublist:sublist (list 0 1 2 3 4 5)
78
+ (list 2 3))))
79
+
80
+ (define-test at-end-superlist
81
+ (assert-equal "superlist" (sublist:sublist (list 0 1 2 3 4 5)
82
+ (list 3 4 5))))
83
+
84
+ #-xlisp-test
85
+ (let ((*print-errors* t)
86
+ (*print-failures* t))
87
+ (run-tests :all))
@@ -0,0 +1,8 @@
1
+ (defpackage #:sublist
2
+ (:use #:common-lisp)
3
+ (:export #:sublist))
4
+
5
+ (in-package #:sublist)
6
+
7
+ (defun sublist (list1 list2)
8
+ "what is list1 of list2 (sublist, superlist, equal or unequal)")
@@ -2,23 +2,26 @@
2
2
 
3
3
  Determine if a triangle is equilateral, isosceles, or scalene.
4
4
 
5
- An _equilateral_ triangle has all three sides the same length.<br/>
5
+ An _equilateral_ triangle has all three sides the same length.
6
+
6
7
  An _isosceles_ triangle has at least two sides the same length. (It is sometimes
7
8
  specified as having exactly two sides the same length, but for the purposes of
8
- this exercise we'll say at least two.)<br/>
9
+ this exercise we'll say at least two.)
10
+
9
11
  A _scalene_ triangle has all sides of different lengths.
10
12
 
11
13
  ## Note
12
14
 
13
- For a shape to be a triangle at all, all sides have to be of length > 0, and
14
- the sum of the lengths of any two sides must be greater than or equal to the
15
+ For a shape to be a triangle at all, all sides have to be of length > 0, and
16
+ the sum of the lengths of any two sides must be greater than or equal to the
15
17
  length of the third side. See [Triangle Inequality](https://en.wikipedia.org/wiki/Triangle_inequality).
16
18
 
17
19
  ## Dig Deeper
18
20
 
19
- The case where the sum of the lengths of two sides _equals_ that of the
20
- third is known as a _degenerate_ triangle - it has zero area and looks like
21
+ The case where the sum of the lengths of two sides _equals_ that of the
22
+ third is known as a _degenerate_ triangle - it has zero area and looks like
21
23
  a single line. Feel free to add your own code/tests to check for degenerate triangles.
24
+
22
25
  ## Setup
23
26
 
24
27
  Check out [Exercism Help](http://exercism.io/languages/lisp) for instructions to
@@ -11,7 +11,7 @@ Trinary numbers contain three symbols: 0, 1, and 2.
11
11
  The last place in a trinary number is the 1's place. The second to last
12
12
  is the 3's place, the third to last is the 9's place, etc.
13
13
 
14
- ```bash
14
+ ```shell
15
15
  # "102012"
16
16
  1 0 2 0 1 2 # the number
17
17
  1*3^5 + 0*3^4 + 2*3^3 + 0*3^2 + 1*3^1 + 2*3^0 # the value
@@ -4,14 +4,13 @@ Given a phrase, count the occurrences of each word in that phrase.
4
4
 
5
5
  For example for the input `"olly olly in come free"`
6
6
 
7
- ```plain
7
+ ```text
8
8
  olly: 2
9
9
  in: 1
10
10
  come: 1
11
11
  free: 1
12
12
  ```
13
13
 
14
-
15
14
  ## Setup
16
15
 
17
16
  Check out [Exercism Help](http://exercism.io/languages/lisp) for instructions to
@@ -236,6 +236,20 @@
236
236
  "Recursion"
237
237
  ]
238
238
  },
239
+ {
240
+ "uuid": "207af8f6-0ffe-e380-d521-7e054bd4e959257c77d",
241
+ "slug": "two-fer",
242
+ "core": false,
243
+ "unlocked_by": "hello-world",
244
+ "difficulty": 1,
245
+ "topics": [
246
+ "Booleans",
247
+ "Strings",
248
+ "Logic",
249
+ "Optional values",
250
+ "Text formatting"
251
+ ]
252
+ },
239
253
  {
240
254
  "uuid": "d773c4ef-c09e-40e4-a7fe-01456cb4a12a",
241
255
  "slug": "hamming",
@@ -980,6 +994,22 @@
980
994
  "Exception handling"
981
995
  ]
982
996
  },
997
+ {
998
+ "core": false,
999
+ "difficulty": 8,
1000
+ "slug": "bowling",
1001
+ "topics": [
1002
+ "arrays",
1003
+ "control-flow-(conditionals)",
1004
+ "control-flow-(loops)",
1005
+ "exception-handling",
1006
+ "games",
1007
+ "parsing",
1008
+ "text-formatting"
1009
+ ],
1010
+ "unlocked_by": "grade-school",
1011
+ "uuid": "dbf26ef1-62ff-4cb1-8ac7-09b022df3b2f"
1012
+ },
983
1013
  {
984
1014
  "uuid": "6a1eee0e-f8d4-446d-9c52-f31c3700af1b",
985
1015
  "slug": "diamond",
@@ -0,0 +1,80 @@
1
+ # Bowling
2
+
3
+ Score a bowling game.
4
+
5
+ Bowling is game where players roll a heavy ball to knock down pins
6
+ arranged in a triangle. Write code to keep track of the score
7
+ of a game of bowling.
8
+
9
+ ## Scoring Bowling
10
+
11
+ A game consists of 10 frames. A frame is composed of one or two balls thrown, with 10 pins standing at the start of the frame. There are three cases for the tabulation of a frame:
12
+
13
+ * An open frame is where a score of less than 10 is recorded for the frame. In this case the score for the frame is the number of pins knocked down after the second throw.
14
+
15
+ * A spare is where all ten pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in the next throw.
16
+
17
+ * A strike is where all ten pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in the next two throws. If a strike is immediately followed by another strike, then the first strike's value cannot be totalled until the next throw.
18
+
19
+ Here is a three frame example:
20
+
21
+ | Frame 1 | Frame 2 | Frame 3 |
22
+ | :-------------: |:-------------:| :---------------------:|
23
+ | X (strike) | 5/ (spare) | 9 0 (open frame) |
24
+
25
+ Frame 1 is (10 + 5 + 5) = 20
26
+
27
+ Frame 2 is (5 + 5 + 9) = 19
28
+
29
+ Frame 3 is (9 + 0) = 9
30
+
31
+ This means the current running total is 48.
32
+
33
+ The tenth frame in the game is a special case. If the player throws a strike or a spare, then they get one extra throw called a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down.
34
+
35
+ For a tenth frame of X1/ (strike and a spare), the total value is 20.
36
+
37
+ For a tenth frame of XXX (three strikes), the total value is 30.
38
+
39
+ ## Setup
40
+
41
+ Go through the setup instructions for ECMAScript to
42
+ install the necessary dependencies:
43
+
44
+ http://exercism.io/languages/ecmascript
45
+
46
+ ## Requirements
47
+
48
+ Install assignment dependencies:
49
+
50
+ ```bash
51
+ $ npm install
52
+ ```
53
+
54
+ Write code to keep track of the score of a game of bowling. It should
55
+ support two operations:
56
+
57
+ * `roll(pins : int)` is called each time the player rolls a ball. The
58
+ argument is the number of pins knocked down.
59
+ * `score() : int` is called only at the very end of the game. It
60
+ returns the total score for that game.
61
+
62
+ ## Making the test suite pass
63
+
64
+ Execute the tests with:
65
+
66
+ ```bash
67
+ $ npm test
68
+ ```
69
+
70
+ In the test suites all tests but the first have been skipped.
71
+
72
+ Once you get a test passing, you can enable the next one by
73
+ changing `xtest` to `test`.
74
+
75
+ ## Source
76
+
77
+ The Bowling Game Kata at but UncleBob [http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata](http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata)
78
+
79
+ ## Submitting Incomplete Solutions
80
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,159 @@
1
+ import Bowling from './bowling';
2
+
3
+ describe('Bowling', () => {
4
+ describe('Check game can be scored correctly.', () => {
5
+ test('should be able to score a game with all gutterballs', () => {
6
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
7
+ expect(new Bowling(rolls).score()).toEqual(0);
8
+ });
9
+
10
+ xtest('should be able to score a game with all open frames', () => {
11
+ const rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6];
12
+ expect(new Bowling(rolls).score()).toEqual(90);
13
+ });
14
+
15
+ xtest('a spare followed by zeros is worth ten points', () => {
16
+ const rolls = [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
17
+ expect(new Bowling(rolls).score()).toEqual(10);
18
+ });
19
+
20
+ xtest('points scored in the roll after a spare are counted twice', () => {
21
+ const rolls = [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
22
+ expect(new Bowling(rolls).score()).toEqual(16);
23
+ });
24
+
25
+ xtest('consecutive spares each get a one roll bonus', () => {
26
+ const rolls = [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
27
+ expect(new Bowling(rolls).score()).toEqual(31);
28
+ });
29
+
30
+ xtest('should allow fill ball when the last frame is a spare', () => {
31
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7];
32
+ expect(new Bowling(rolls).score()).toEqual(17);
33
+ });
34
+
35
+ xtest('a strike earns ten points in a frame with a single roll', () => {
36
+ const rolls = [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
37
+ expect(new Bowling(rolls).score()).toEqual(10);
38
+ });
39
+
40
+ xtest('points scored in the two rolls after a strike are counted twice as a bonus', () => {
41
+ const rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
42
+ expect(new Bowling(rolls).score()).toEqual(26);
43
+ });
44
+
45
+ xtest('should be able to score multiple strikes in a row', () => {
46
+ const rolls = [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
47
+ expect(new Bowling(rolls).score()).toEqual(81);
48
+ });
49
+
50
+ xtest('should allow fill balls when the last frame is a strike', () => {
51
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1];
52
+ expect(new Bowling(rolls).score()).toEqual(18);
53
+ });
54
+
55
+ xtest('rolling a spare with the two roll bonus does not get a bonus roll', () => {
56
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3];
57
+ expect(new Bowling(rolls).score()).toEqual(20);
58
+ });
59
+
60
+ xtest('strikes with the two roll bonus do not get bonus rolls', () => {
61
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10];
62
+ expect(new Bowling(rolls).score()).toEqual(30);
63
+ });
64
+
65
+ xtest('a strike with the one roll bonus after a spare in the last frame does not get a bonus', () => {
66
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10];
67
+ expect(new Bowling(rolls).score()).toEqual(20);
68
+ });
69
+
70
+ xtest('should be able to score a perfect game', () => {
71
+ const rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10];
72
+ expect(new Bowling(rolls).score()).toEqual(300);
73
+ });
74
+ });
75
+
76
+ describe('Check game rules.', () => {
77
+ xtest('rolls can not score negative points', () => {
78
+ const rolls = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
79
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
80
+ new Error('Pins must have a value from 0 to 10'),
81
+ );
82
+ });
83
+
84
+ xtest('a roll can not score more than 10 points', () => {
85
+ const rolls = [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
86
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
87
+ new Error('Pins must have a value from 0 to 10'),
88
+ );
89
+ });
90
+
91
+ xtest('two rolls in a frame can not score more than 10 points', () => {
92
+ const rolls = [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
93
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
94
+ new Error('Pin count exceeds pins on the lane'),
95
+ );
96
+ });
97
+
98
+ xtest('two bonus rolls after a strike in the last frame can not score more than 10 points', () => {
99
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6];
100
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
101
+ new Error('Pin count exceeds pins on the lane'),
102
+ );
103
+ });
104
+
105
+ xtest('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', () => {
106
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6];
107
+ expect(new Bowling(rolls).score()).toEqual(26);
108
+ });
109
+
110
+ xtest('the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike', () => {
111
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10];
112
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
113
+ new Error('Pin count exceeds pins on the lane'),
114
+ );
115
+ });
116
+
117
+ xtest('an unstarted game can not be scored', () => {
118
+ const rolls = [];
119
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
120
+ new Error('Score cannot be taken until the end of the game'),
121
+ );
122
+ });
123
+
124
+ xtest('an incomplete game can not be scored', () => {
125
+ const rolls = [0, 0];
126
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
127
+ new Error('Score cannot be taken until the end of the game'),
128
+ );
129
+ });
130
+
131
+ xtest('a game with more than ten frames and no last frame spare or strike can not be scored', () => {
132
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
133
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
134
+ new Error('Should not be able to roll after game is over'),
135
+ );
136
+ });
137
+
138
+ xtest('bonus rolls for a strike in the last frame must be rolled before score can be calculated', () => {
139
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10];
140
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
141
+ new Error('Score cannot be taken until the end of the game'),
142
+ );
143
+ });
144
+
145
+ xtest('both bonus rolls for a strike in the last frame must be rolled before score can be calculated', () => {
146
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10];
147
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
148
+ new Error('Score cannot be taken until the end of the game'),
149
+ );
150
+ });
151
+
152
+ xtest('bonus roll for a spare in the last frame must be rolled before score can be calculated', () => {
153
+ const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3];
154
+ expect(() => { new Bowling(rolls).score(); }).toThrow(
155
+ new Error('Score cannot be taken until the end of the game'),
156
+ );
157
+ });
158
+ });
159
+ });