trackler 2.0.3.8 → 2.0.3.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/common/exercises/book-store/description.md +67 -0
  3. data/common/exercises/book-store/metadata.yml +4 -0
  4. data/lib/trackler/version.rb +1 -1
  5. data/tracks/crystal/exercises/difference-of-squares/src/difference_of_squares.cr +1 -0
  6. data/tracks/ecmascript/exercises/custom-set/package.json +1 -0
  7. data/tracks/ecmascript/exercises/palindrome-products/palindrome-products.js +18 -18
  8. data/tracks/fsharp/docs/INSTALLATION.md +2 -3
  9. data/tracks/fsharp/docs/TESTS.md +1 -1
  10. data/tracks/fsharp/exercises/accumulate/HINTS.md +3 -0
  11. data/tracks/fsharp/exercises/diamond/HINTS.md +2 -0
  12. data/tracks/fsharp/exercises/grains/HINTS.md +1 -1
  13. data/tracks/fsharp/exercises/hello-world/HINTS.md +1 -1
  14. data/tracks/fsharp/exercises/parallel-letter-frequency/HINTS.md +3 -0
  15. data/tracks/fsharp/exercises/poker/HINTS.md +2 -0
  16. data/tracks/fsharp/exercises/raindrops/HINTS.md +2 -0
  17. data/tracks/fsharp/exercises/space-age/HINTS.md +3 -0
  18. data/tracks/javascript/exercises/bowling/bowling.spec.js +83 -63
  19. data/tracks/ocaml/config.json +5 -0
  20. data/tracks/ocaml/exercises/leap/test.ml +7 -13
  21. data/tracks/ocaml/exercises/robot-name/.merlin +3 -0
  22. data/tracks/ocaml/exercises/robot-name/Makefile +11 -0
  23. data/tracks/ocaml/exercises/robot-name/example.ml +26 -0
  24. data/tracks/ocaml/exercises/robot-name/robot_name.mli +7 -0
  25. data/tracks/ocaml/exercises/robot-name/test.ml +64 -0
  26. data/tracks/ocaml/tools/test-generator/Makefile +3 -0
  27. data/tracks/ocaml/tools/test-generator/README.md +1 -0
  28. data/tracks/ocaml/tools/test-generator/src/canonical_data_checker.ml +23 -0
  29. data/tracks/ocaml/tools/test-generator/src/controller.ml +12 -0
  30. data/tracks/ocaml/tools/test-generator/src/parser.ml +29 -22
  31. data/tracks/ocaml/tools/test-generator/src/utils.ml +8 -0
  32. data/tracks/ocaml/tools/test-generator/test/clock.json +437 -0
  33. data/tracks/ocaml/tools/test-generator/test/parser_test.ml +18 -4
  34. data/tracks/ocaml/tools/test-generator/test/with-methods-key.json +22 -0
  35. data/tracks/perl6/config.json +5 -0
  36. data/tracks/perl6/exercises/wordy/Example.p6 +16 -0
  37. data/tracks/perl6/exercises/wordy/cases.json +89 -0
  38. data/tracks/perl6/exercises/wordy/wordy.t +29 -0
  39. data/tracks/ruby/exercises/acronym/{.version → .meta/.version} +0 -0
  40. data/tracks/ruby/exercises/alphametics/{.version → .meta/.version} +0 -0
  41. data/tracks/ruby/exercises/anagram/{.version → .meta/.version} +0 -0
  42. data/tracks/ruby/exercises/binary/{.version → .meta/.version} +0 -0
  43. data/tracks/ruby/exercises/bowling/{.version → .meta/.version} +0 -0
  44. data/tracks/ruby/exercises/bracket-push/{.version → .meta/.version} +0 -0
  45. data/tracks/ruby/exercises/clock/{.version → .meta/.version} +0 -0
  46. data/tracks/ruby/exercises/connect/{.version → .meta/.version} +0 -0
  47. data/tracks/ruby/exercises/custom-set/{.version → .meta/.version} +0 -0
  48. data/tracks/ruby/exercises/difference-of-squares/{.version → .meta/.version} +0 -0
  49. data/tracks/ruby/exercises/dominoes/{.version → .meta/.version} +0 -0
  50. data/tracks/ruby/exercises/gigasecond/{.version → .meta/.version} +0 -0
  51. data/tracks/ruby/exercises/hamming/{.version → .meta/.version} +0 -0
  52. data/tracks/ruby/exercises/hello-world/{.version → .meta/.version} +0 -0
  53. data/tracks/ruby/exercises/isogram/{.version → .meta/.version} +0 -0
  54. data/tracks/ruby/exercises/largest-series-product/{.version → .meta/.version} +0 -0
  55. data/tracks/ruby/exercises/leap/{.version → .meta/.version} +0 -0
  56. data/tracks/ruby/exercises/nth-prime/{.version → .meta/.version} +0 -0
  57. data/tracks/ruby/exercises/pangram/{.version → .meta/.version} +0 -0
  58. data/tracks/ruby/exercises/queen-attack/{.version → .meta/.version} +0 -0
  59. data/tracks/ruby/exercises/raindrops/{.version → .meta/.version} +0 -0
  60. data/tracks/ruby/exercises/rna-transcription/{.version → .meta/.version} +0 -0
  61. data/tracks/ruby/exercises/roman-numerals/{.version → .meta/.version} +0 -0
  62. data/tracks/ruby/exercises/run-length-encoding/{.version → .meta/.version} +0 -0
  63. data/tracks/ruby/exercises/sieve/{.version → .meta/.version} +0 -0
  64. data/tracks/ruby/exercises/tournament/{.version → .meta/.version} +0 -0
  65. data/tracks/ruby/exercises/transpose/{.version → .meta/.version} +0 -0
  66. data/tracks/ruby/exercises/triangle/{.version → .meta/.version} +0 -0
  67. data/tracks/ruby/exercises/two-bucket/{.version → .meta/.version} +0 -0
  68. data/tracks/ruby/exercises/word-count/{.version → .meta/.version} +0 -0
  69. data/tracks/ruby/lib/generator.rb +15 -4
  70. data/tracks/rust/config.json +1 -0
  71. data/tracks/rust/exercises/largest-series-product/.gitignore +7 -0
  72. data/tracks/rust/exercises/largest-series-product/Cargo.toml +3 -0
  73. data/tracks/rust/exercises/largest-series-product/HINTS.md +6 -0
  74. data/tracks/rust/exercises/largest-series-product/example.rs +22 -0
  75. data/tracks/rust/exercises/largest-series-product/tests/largest-series-product.rs +105 -0
  76. data/tracks/rust/problems.md +1 -0
  77. data/tracks/scala/.gitignore +1 -0
  78. data/tracks/scala/exercises/accumulate/src/test/scala/{accumulate_test.scala → AccumulateTest.scala} +0 -0
  79. data/tracks/scala/exercises/allergies/src/test/scala/{allergies_test.scala → AllergiesTest.scala} +0 -0
  80. data/tracks/scala/exercises/anagram/src/test/scala/{anagram_test.scala → AnagramTest.scala} +0 -0
  81. data/tracks/scala/exercises/binary/src/test/scala/{binary_test.scala → BinaryTest.scala} +0 -0
  82. data/tracks/scala/exercises/bob/src/test/scala/{bob_test.scala → BobTest.scala} +0 -0
  83. data/tracks/scala/exercises/difference-of-squares/src/test/scala/{squares_test.scala → SquaresTest.scala} +0 -0
  84. data/tracks/scala/exercises/etl/src/test/scala/{etl_test.scala → EtlTest.scala} +0 -0
  85. data/tracks/scala/exercises/gigasecond/src/test/scala/{gigasecond_test.scala → GigasecondTest.scala} +0 -0
  86. data/tracks/scala/exercises/grade-school/src/test/scala/{grade_school_test.scala → GradeSchoolTest.scala} +0 -0
  87. data/tracks/scala/exercises/grains/src/test/scala/{grains_test.scala → GrainsTest.scala} +0 -0
  88. data/tracks/scala/exercises/hamming/src/test/scala/{hamming_test.scala → HammingTest.scala} +0 -0
  89. data/tracks/scala/exercises/hello-world/src/test/scala/HelloWorldTest.scala +2 -0
  90. data/tracks/scala/exercises/leap/src/test/scala/{leap_test.scala → LeapTest.scala} +0 -0
  91. data/tracks/scala/exercises/meetup/src/test/scala/{meetup_test.scala → MeetupTest.scala} +0 -0
  92. data/tracks/scala/exercises/nth-prime/example.scala +3 -1
  93. data/tracks/scala/exercises/nth-prime/src/test/scala/PrimeTest.scala +11 -6
  94. data/tracks/scala/exercises/nucleotide-count/src/test/scala/{nucleotide_count_test.scala → NucleotideCountTest.scala} +0 -0
  95. data/tracks/scala/exercises/palindrome-products/src/test/scala/PalindromeProductsTest.scala +7 -0
  96. data/tracks/scala/exercises/pangram/src/test/scala/{PangramsTest.scala → PangramTest.scala} +0 -0
  97. data/tracks/scala/exercises/parallel-letter-frequency/HINTS.md +26 -0
  98. data/tracks/scala/exercises/phone-number/src/test/scala/{phone_number_test.scala → PhoneNumberTest.scala} +0 -0
  99. data/tracks/scala/exercises/prime-factors/src/test/scala/{primefactors_test.scala → PrimefactorsTest.scala} +10 -0
  100. data/tracks/scala/exercises/raindrops/src/test/scala/{raindrops_test.scala → RaindropsTest.scala} +15 -0
  101. data/tracks/scala/exercises/rna-transcription/src/test/scala/{transcription_test.scala → RnaTranscriptionTest.scala} +8 -0
  102. data/tracks/scala/exercises/robot-name/src/test/scala/{robot_name_test.scala → RobotNameTest.scala} +0 -0
  103. data/tracks/scala/exercises/roman-numerals/src/test/scala/{roman_numerals_test.scala → RomanNumeralsTest.scala} +17 -0
  104. data/tracks/scala/exercises/saddle-points/src/test/scala/{SaddlePointsSpecs.scala → SaddlePointsTest.scala} +3 -0
  105. data/tracks/scala/exercises/scrabble-score/src/test/scala/{scrabble_score_test.scala → ScrabbleScoreTest.scala} +0 -0
  106. data/tracks/scala/exercises/sgf-parsing/src/test/scala/SgfTest.scala +1 -0
  107. data/tracks/scala/exercises/space-age/src/test/scala/{space_age_test.scala → SpaceAgeTest.scala} +0 -0
  108. data/tracks/scala/exercises/sublist/src/test/scala/{sublist_test.scala → SublistTest.scala} +0 -0
  109. data/tracks/scala/exercises/triangle/src/test/scala/{triangle_test.scala → TriangleTest.scala} +7 -0
  110. data/tracks/scala/exercises/word-count/src/test/scala/{word_count_test.scala → WordCountTest.scala} +0 -0
  111. data/tracks/scala/exercises/zipper/src/test/scala/ZipperTest.scala +7 -0
  112. data/tracks/swift/config.json +19 -0
  113. data/tracks/swift/docs/TESTS.md +114 -23
  114. data/tracks/swift/exercises/beer-song/BeerSongExample.swift +32 -0
  115. data/tracks/swift/exercises/beer-song/BeerSongTest.swift +44 -0
  116. data/tracks/swift/exercises/hello-world/{helloWorldExample.swift → HelloWorldExample.swift} +4 -0
  117. data/tracks/swift/exercises/hello-world/{helloWorldTest/helloWorldTest.swift → helloWorldTest.swift} +1 -1
  118. data/tracks/swift/exercises/sublist/SubListTest.swift +95 -0
  119. data/tracks/swift/exercises/sublist/SublistExample.swift +72 -0
  120. data/tracks/swift/img/page_assets/001-splash.png +0 -0
  121. data/tracks/swift/img/page_assets/002-templateChooser.png +0 -0
  122. data/tracks/swift/img/page_assets/003-nameProject.jpg +0 -0
  123. data/tracks/swift/img/page_assets/004-saveProject.jpg +0 -0
  124. data/tracks/swift/img/page_assets/005-folderLayout.png +0 -0
  125. data/tracks/swift/img/page_assets/006-newProjectInitial.jpg +0 -0
  126. data/tracks/swift/img/page_assets/007-fileInspectorUpdate.png +0 -0
  127. data/tracks/swift/img/page_assets/008-templateChooserSwift.png +0 -0
  128. data/tracks/swift/img/page_assets/009-importTestSource.png +0 -0
  129. data/tracks/swift/img/page_assets/010-testsImportExample.png +0 -0
  130. data/tracks/swift/img/page_assets/011-finalLayoutExample.png +0 -0
  131. data/tracks/swift/xcodeProject/xSwift.xcodeproj/project.pbxproj +36 -56
  132. metadata +103 -65
  133. data/tracks/swift/exercises/hello-world/helloWorld.swift +0 -1
  134. data/tracks/swift/exercises/hello-world/helloWorld.xcodeproj/project.pbxproj +0 -256
  135. data/tracks/swift/exercises/hello-world/helloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  136. data/tracks/swift/exercises/hello-world/helloWorldTest/Info.plist +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 26859b54fc9507930d1491868635aa16867347f6
4
- data.tar.gz: 9b58994afd40bf481622cad4dcc0bb4528078ff8
3
+ metadata.gz: 7a91f7979567f492ab8b002b66d7fcf8cd716625
4
+ data.tar.gz: 840ec796d75143f63a21446537e2c4e22f496cbd
5
5
  SHA512:
6
- metadata.gz: 7f55463ac98a1e18ded0523c929796b44a226ead128bb7015de7161469b87e9dca58b4b2353ec203ce2e8e9f7d8c2deaa811991bcefa6beb32acf880312a684a
7
- data.tar.gz: fd3ea88f64020af3af7fa037ef1de5afb2ad895873ef15d9e21efb0c94728c79faaeb30fada44974a6da4ee367789c6cfcee0f8d5d84d5d5177b2433540f41b8
6
+ metadata.gz: cda059d0a0316df945dc469f2900a469475254447508e10b91fdf51b07633a83e5c9f931fc4b2441be111168e03ef48bd5af8c79c3f7ce91e3f0504c121021ed
7
+ data.tar.gz: 952113e3d6b6b64e8a345fcb867dbe37a215f93e452b76f8d02ec93494d8cb622bbab4e7dbbacc7a532b2cf279f9611b10b2e21c8ddbdc58a1a65bae40bbd77a
@@ -0,0 +1,67 @@
1
+ To try and encourage more sales of the 5 different books
2
+ they sell of a popular series, a bookshop has decided to
3
+ offer discounts of multi-book purchases.
4
+
5
+ One copy of any of the five books costs $8.
6
+
7
+ If, however, you buy two different books, you get a 5%
8
+ discount on those two books.
9
+
10
+ If you buy 3 different books, you get a 10% discount.
11
+
12
+ If you buy 4 different books, you get a 20% discount.
13
+
14
+ If you buy all 5, you get a 25% discount.
15
+
16
+ Note: that if you buy four books, of which 3 are
17
+ different titles, you get a 10% discount on the 3 that
18
+ form part of a set, but the fourth book still costs $8.
19
+
20
+ Your mission is to write a piece of code to calculate the
21
+ price of any conceivable shopping basket (containing only
22
+ books of the same series), giving as big a discount as
23
+ possible.
24
+
25
+ For example, how much does this basket of books cost?
26
+
27
+ - 2 copies of the first book
28
+ - 2 copies of the second book
29
+ - 2 copies of the third book
30
+ - 1 copy of the fourth book
31
+ - 1 copy of the fifth book
32
+
33
+ One way of grouping these 8 books is:
34
+
35
+ - 1 group of 5 --> 25% discount (1st,2nd,3rd,4th,5th)
36
+ - +1 group of 3 --> 10% discount (1st,2nd,3rd)
37
+
38
+ This would give a total of:
39
+
40
+ - 5 books at a 25% discount
41
+ - +3 books at a 10% discount
42
+
43
+ Resulting in:
44
+
45
+ - 5 x (8 - 2.00) == 5 x 6.00 == $30.00
46
+ - +3 x (8 - 0.80) == 3 x 7.20 == $21.60
47
+
48
+ For a total of $51.60
49
+
50
+ However, a different way to group these 8 books is:
51
+
52
+ - 1 group of 4 books --> 20% discount (1st,2nd,3rd,4th)
53
+ - +1 group of 4 books --> 20% discount (1st,2nd,3rd,5th)
54
+
55
+ This would give a total of:
56
+
57
+ - 4 books at a 20% discount
58
+ - +4 books at a 20% discount
59
+
60
+ Resulting in:
61
+
62
+ - 4 x (8 - 1.60) == 4 x 6.40 == $25.60
63
+ - +4 x (8 - 1.60) == 4 x 6.40 == $25.60
64
+
65
+ For a total of $51.20
66
+
67
+ And $51.20 is the price with the biggest discount.
@@ -0,0 +1,4 @@
1
+ ---
2
+ blurb: "To try and encourage more sales of different books from a popular 5 book series, a bookshop has decided to offer discounts of multiple-book purchases."
3
+ source: "Inspired by the harry potter kata from Cyber-Dojo."
4
+ source_url: "http://cyber-dojo.org"
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.0.3.8"
2
+ VERSION = "2.0.3.9"
3
3
  end
@@ -0,0 +1 @@
1
+ # Please implement your solution to difference-of-squares in this file
@@ -1,3 +1,4 @@
1
+ {
1
2
  "name": "xecmascript",
2
3
  "version": "0.0.0",
3
4
  "description": "Exercism exercises in ECMAScript 6.",
@@ -1,18 +1,18 @@
1
- -/**
2
- - * Generate palindrome-products table and calculate largest/smallest.
3
- - *
4
- - * @param {Number} [minFactor]
5
- - * Minimum Factor
6
- - *
7
- - * @param {Number} [maxFactor]
8
- - * Maximum Factor
9
- - *
10
- - * @return {{largest: number, smallest: number}}
11
- - */
12
- -function generate({ minFactor = 1, maxFactor = Number.MAX_VALUE }) {
13
- -//
14
- -// YOUR CODE GOES HERE
15
- -//
16
- -}
17
- -
18
- -export default generate;
1
+ /**
2
+ * Generate palindrome-products table and calculate largest/smallest.
3
+ *
4
+ * @param {Number} [minFactor]
5
+ * Minimum Factor
6
+ *
7
+ * @param {Number} [maxFactor]
8
+ * Maximum Factor
9
+ *
10
+ * @return {{largest: number, smallest: number}}
11
+ */
12
+ function generate({ minFactor = 1, maxFactor = Number.MAX_VALUE }) {
13
+ //
14
+ // YOUR CODE GOES HERE
15
+ //
16
+ }
17
+
18
+ export default generate;
@@ -5,10 +5,9 @@ Install [Xamarin Studio](http://xamarin.com/download).
5
5
  While Xamarin is most known for creating iOS and Android applications, it's still a perfect IDE to create F# console
6
6
  or library projects which is all that's needed for Exercism.
7
7
 
8
- Once installed and running, click on new solution and you'll find the library project to select. Don't forget to click the
9
- lanugage drop down to select F# since it defaults to C#.
8
+ Once installed and running, you can validate the installation by starting Xamarin creating a new solution. On the left hand side select .NET, and on the right hand side select Library. Library should have a little button-shapped drop down box to it's right that says C#. Click it and you'll see you can also choose F#.
10
9
 
11
- ![Xamarin New Project](http://x.exercism.io/v3/tracks/fsharp/docs/img/xamarin-fsharp.jpg)
10
+ <img alt="Xamarin New Projct" src="http://x.exercism.io/v3/tracks/fsharp/docs/img/xamarin-fsharp.jpg" style="width:100%; height: 100%;">
12
11
 
13
12
  #### Linux
14
13
  The [F# Foundation](http://fsharp.org/) has detailed instructions on different options to install F# on [Linux](http://fsharp.org/use/linux/).
@@ -28,7 +28,7 @@ Now you can have fun learning F# and run your code against the tests!
28
28
  ### Mac
29
29
  Xamarin Studio also ships with NUnit. From the new project dialog, just select an NUnit class library.
30
30
 
31
- ![Xamarin NUnit](http://x.exercism.io/v3/tracks/fsharp/docs/img/xamarin-fsharp-nunit.jpg)
31
+ <img alt="Xamarin NUnit" src=" http://x.exercism.io/v3/tracks/fsharp/docs/img/xamarin-fsharp-nunit.jpg" style="height: 100%; width: 100%;" />
32
32
 
33
33
  From here you can write NUnit tests right away. To run the tests open the `Unit Tests` pad within
34
34
  Xamarin (View -> Pads -> Unit Tests).
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ For this exercise the following F# feature comes in handy:
3
+ - [Tail recursion](https://blogs.msdn.microsoft.com/fsharpteam/2011/07/08/tail-calls-in-f/) Prevent stack overflows with large input by using tail recursion. While there are no test cases checking explicitly for this, using tail recursion leads to a more performant solution. Another good resource on tail recursion is [this blog post](http://blog.ploeh.dk/2015/12/22/tail-recurse/).
@@ -0,0 +1,2 @@
1
+ ## Hints
2
+ - Testing this one can be tricky without simply hardcoding a bunch of inputs and outputs. [Property based testing](https://fsharpforfunandprofit.com/posts/property-based-testing/) is another way to think about testing that allows you to more easily test this type of algorithm.
@@ -1,4 +1,4 @@
1
1
  ## Hints
2
- For this exercise the following F# feature comes in handy:
2
+ For this exercise the following F# features come in handy:
3
3
  - [BigInt](https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/numerics.biginteger-structure-%5Bfsharp%5D)
4
4
  - [Seq.sumBy](https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.sumby%5B't,%5Eu%5D-function-%5Bfsharp%5D) is a condensed format to apply a function to a sequence and then sum the results
@@ -1,5 +1,5 @@
1
1
  ## Hints
2
- For this exercise the following F# feature comes in handy:
2
+ For this exercise the following F# features come in handy:
3
3
  - [Match Expressions](https://fsharpforfunandprofit.com/posts/match-expression/) Also known as pattern matching which is like a switch statement on steriods. It's a very powerful ability in the F# language and will come in handy in many of the exercises. While this example can be trivially solved with an if/else, pattern matching is more idiomatic.
4
4
  - [sprintf](https://fsharpforfunandprofit.com/posts/printf/) While F# supports string concatenation using sprintf leads to easier to read solutions and is also idiomatic
5
5
  - [defaultArg](https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/operators.defaultarg%5B't%5D-function-%5Bfsharp%5D) Default arg is useful when extracting a value from an option type and providing a value when None is encountered.
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ For this exercise the following F# feature comes in handy:
3
+ - [Asynchronous programming](https://fsharpforfunandprofit.com/posts/concurrency-async-and-parallel/) .NET has asynchronous functionality built-in which enables you to run things in parallel (assuming you have a multi-core processor which is becoming more an more common) easily
@@ -0,0 +1,2 @@
1
+ ## Hints
2
+ - [Designing with types](http://fsharpforfunandprofit.com/series/designing-with-types.html) To come up with a clean and easy to read solution for this make sure to choose the right types to represent the different parts of the problem (think of suits, values, cards, etc)
@@ -0,0 +1,2 @@
1
+ ## Hints
2
+ - Think of this in a generic way. If you're familiar with the (fizz buzz)[https://en.wikipedia.org/wiki/Fizz_buzz] problem this is similar except there are three conditions instead of two. How would you implement this knowing that one day we might want to extend to four, five, or even ten types of raindrops?
@@ -0,0 +1,3 @@
1
+ ## Hints
2
+ - Try to focus on minimizing the amount of code duplication. If you find yourself doing a lot of copy/paste take a step back and think about how the code can be refactored
3
+ - [Pattern matching](https://fsharpforfunandprofit.com/posts/match-expression/) is more idiomatic than using dictionaries to translate values
@@ -2,39 +2,44 @@ var Bowling = require('./bowling');
2
2
 
3
3
  describe('Bowling', function() {
4
4
  describe('Check game can be scored correctly.', function() {
5
- it('should be able to score open frame', function() {
6
- var rolls = [3, 4, 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(7);
5
+ it('should be able to score a game with all gutterballs', function() {
6
+ var 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
8
  });
9
9
 
10
- xit('should be able to score multiple frames', function() {
11
- var rolls = [3, 4, 2, 3, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
12
- expect(new Bowling(rolls).score()).toEqual(19);
10
+ xit('should be able to score a game with all open frames', function() {
11
+ var 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
13
  });
14
14
 
15
- xit('should be able to score a game with all gutterballs', function() {
16
- var rolls = [0, 0, 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(0);
15
+ xit('a spare followed by zeros is worth ten points', function() {
16
+ var 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
18
  });
19
19
 
20
- xit('should be able to score a game with all single pin rolls', function() {
21
- var rolls = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
22
- expect(new Bowling(rolls).score()).toEqual(20);
20
+ xit('points scored in the roll after a spare are counted twice', function() {
21
+ var 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
23
  });
24
24
 
25
- xit('should be able to score a game with all open frames', function() {
26
- var rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6];
27
- expect(new Bowling(rolls).score()).toEqual(90);
25
+ xit('consecutive spares each get a one roll bonus', function() {
26
+ var 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
28
  });
29
29
 
30
- xit('should be able to score a strike not in the last frame', function() {
31
- var rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
32
- expect(new Bowling(rolls).score()).toEqual(26);
30
+ xit('should allow fill ball when the last frame is a spare', function() {
31
+ var 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
33
  });
34
34
 
35
- xit('should be able to score a spare not in the last frame', function() {
36
- var rolls = [5, 5, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
37
- expect(new Bowling(rolls).score()).toEqual(20);
35
+ xit('a strike earns ten points in a frame with a single roll', function() {
36
+ var 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
+ xit('points scored in the two rolls after a strike are counted twice as a bonus', function() {
41
+ var 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);
38
43
  });
39
44
 
40
45
  xit('should be able to score multiple strikes in a row', function() {
@@ -42,26 +47,26 @@ describe('Bowling', function() {
42
47
  expect(new Bowling(rolls).score()).toEqual(81);
43
48
  });
44
49
 
45
- xit('should be able to score multiple spares in a row', function() {
46
- var rolls = [5, 5, 3, 7, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
47
- expect(new Bowling(rolls).score()).toEqual(32);
48
- });
49
-
50
50
  xit('should allow fill balls when the last frame is a strike', function() {
51
51
  var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1];
52
52
  expect(new Bowling(rolls).score()).toEqual(18);
53
53
  });
54
54
 
55
- xit('should allow fill ball when the last frame is a spare', function() {
56
- var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 7];
57
- expect(new Bowling(rolls).score()).toEqual(17);
55
+ xit('rolling a spare with the two roll bonus does not get a bonus roll', function() {
56
+ var 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
58
  });
59
59
 
60
- xit('should allow fill balls to be a strike', function() {
60
+ xit('strikes with the two roll bonus do not get bonus rolls', function() {
61
61
  var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10];
62
62
  expect(new Bowling(rolls).score()).toEqual(30);
63
63
  });
64
64
 
65
+ xit('a strike with the one roll bonus after a spare in the last frame does not get a bonus', function() {
66
+ var 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
+
65
70
  xit('should be able to score a perfect game', function() {
66
71
  var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10];
67
72
  expect(new Bowling(rolls).score()).toEqual(300);
@@ -69,60 +74,75 @@ describe('Bowling', function() {
69
74
  });
70
75
 
71
76
  describe('Check game rules.', function() {
72
- xit('should not allow rolls with negative pins', function() {
73
- var rolls = [-1];
77
+ xit('rolls can not score negative points', function() {
78
+ var rolls = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
74
79
  expect(function() { new Bowling(rolls).score(); }).toThrow(
75
- new Error('Pins must have a value from 0 to 10')
76
- );
77
- });
80
+ new Error('Pins must have a value from 0 to 10'));
81
+ });
78
82
 
79
- xit('should not allow rolls better than strike', function() {
80
- var rolls = [11];
83
+ xit('a roll can not score more than 10 points', function() {
84
+ var rolls = [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
81
85
  expect(function() { new Bowling(rolls).score(); }).toThrow(
82
- new Error('Pins must have a value from 0 to 10')
83
- );
84
- });
86
+ new Error('Pins must have a value from 0 to 10'));
87
+ });
85
88
 
86
- xit('should not allow two normal rolls better than strike', function() {
87
- var rolls = [5, 6];
89
+ xit('two rolls in a frame can not score more than 10 points', function() {
90
+ var rolls = [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
88
91
  expect(function() { new Bowling(rolls).score(); }).toThrow(
89
- new Error('Pin count exceeds pins on the lane')
90
- );
92
+ new Error('Pin count exceeds pins on the lane'));
93
+ });
94
+
95
+ xit('two bonus rolls after a strike in the last frame can not score more than 10 points', function() {
96
+ var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6];
97
+ expect(function() { new Bowling(rolls).score(); }).toThrow(
98
+ new Error('Pin count exceeds pins on the lane'));
99
+ });
100
+
101
+ xit('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', function() {
102
+ var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6];
103
+ expect(new Bowling(rolls).score()).toEqual(26);
91
104
  });
92
105
 
93
- xit('should not allow two normal rolls better than strike in last frame', function() {
94
- var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6];
106
+ xit('the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike', function() {
107
+ var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10];
95
108
  expect(function() { new Bowling(rolls).score(); }).toThrow(
96
- new Error('Pin count exceeds pins on the lane')
97
- );
109
+ new Error('Pin count exceeds pins on the lane'));
98
110
  });
99
111
 
100
- xit('should not allow to take score at the beginning of the game', function() {
112
+ xit('an unstarted game can not be scored', function() {
101
113
  var rolls = [];
102
114
  expect(function() { new Bowling(rolls).score(); }).toThrow(
103
- new Error('Score cannot be taken until the end of the game')
104
- );
115
+ new Error('Score cannot be taken until the end of the game'));
105
116
  });
106
117
 
107
- xit('should not allow to take score before the game has ended', function() {
108
- var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
118
+ xit('an incomplete game can not be scored', function() {
119
+ var rolls = [0, 0];
109
120
  expect(function() { new Bowling(rolls).score(); }).toThrow(
110
- new Error('Score cannot be taken until the end of the game')
111
- );
121
+ new Error('Score cannot be taken until the end of the game'));
112
122
  });
113
123
 
114
- xit('should not allow rolls after the tenth frame', function() {
124
+ xit('a game with more than ten frames and no last frame spare or strike can not be scored', function() {
115
125
  var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
116
126
  expect(function() { new Bowling(rolls).score(); }).toThrow(
117
- new Error('Should not be able to roll after game is over')
118
- );
127
+ new Error('Should not be able to roll after game is over'));
128
+ });
129
+
130
+ xit('bonus rolls for a strike in the last frame must be rolled before score can be calculated', function() {
131
+ var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10];
132
+ expect(function() { new Bowling(rolls).score(); }).toThrow(
133
+ new Error('Score cannot be taken until the end of the game'));
134
+ });
135
+
136
+ xit('both bonus rolls for a strike in the last frame must be rolled before score can be calculated', function() {
137
+ var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10];
138
+ expect(function() { new Bowling(rolls).score(); }).toThrow(
139
+ new Error('Score cannot be taken until the end of the game'));
119
140
  });
120
141
 
121
- xit('should not calculate score before fill balls have been played', function() {
122
- var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10];
142
+ xit('bonus roll for a spare in the last frame must be rolled before score can be calculated', function() {
143
+ var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3];
123
144
  expect(function() { new Bowling(rolls).score(); }).toThrow(
124
- new Error('Score cannot be taken until the end of the game')
125
- );
145
+ new Error('Score cannot be taken until the end of the game'));
126
146
  });
127
147
  });
128
- });
148
+ });
@@ -121,6 +121,11 @@
121
121
  "difficulty": 5,
122
122
  "topics": []
123
123
  },
124
+ {
125
+ "slug": "robot-name",
126
+ "difficulty": 6,
127
+ "topics": ["Randomness", "Mutable state"]
128
+ },
124
129
  {
125
130
  "slug": "list-ops",
126
131
  "difficulty": 6,
@@ -5,19 +5,13 @@ open Leap
5
5
  let ae exp got _test_ctxt = assert_equal exp got
6
6
 
7
7
  let tests = [
8
- "leap year in twentieth century" >::
9
- ae true (leap_year 1996);
10
- "odd standard year in twentieth century" >::
11
- ae false (leap_year 1997);
12
- "even standard year in twentieth century" >::
13
- ae false (leap_year 1998);
14
- "standard year in nineteenth century" >::
15
- ae false (leap_year 1900);
16
- "standard year in eighteenth century" >::
17
- ae false (leap_year 1800);
18
- "leap year twenty four hundred" >::
19
- ae true (leap_year 2400);
20
- "leap year two thousand" >::
8
+ "year not divisible by 4: common year" >::
9
+ ae false (leap_year 2015);
10
+ "year divisible by 4, not divisible by 100: leap year" >::
11
+ ae true (leap_year 2016);
12
+ "year divisible by 100, not divisible by 400: common year" >::
13
+ ae false (leap_year 2100);
14
+ "year divisible by 400: leap year" >::
21
15
  ae true (leap_year 2000);
22
16
  ]
23
17