trackler 2.0.0.1 → 2.0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (226) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bump-content +3 -1
  3. data/bin/verify-metadata +2 -2
  4. data/common/exercises/alphametics/canonical-data.json +19 -9
  5. data/common/exercises/food-chain/canonical-data.json +7 -1
  6. data/common/exercises/grains/canonical-data.json +66 -0
  7. data/common/exercises/raindrops/description.md +4 -5
  8. data/common/exercises/triangle/canonical-data.json +81 -54
  9. data/lib/trackler/version.rb +1 -1
  10. data/tracks/c/config.json +26 -19
  11. data/tracks/c/exercises/allergies/makefile +15 -0
  12. data/tracks/c/exercises/allergies/src/allergies.h +21 -0
  13. data/tracks/c/exercises/allergies/src/example.c +32 -0
  14. data/tracks/c/exercises/allergies/src/example.h +26 -0
  15. data/tracks/c/exercises/allergies/test/test_allergies.c +203 -0
  16. data/tracks/c/exercises/allergies/test/vendor/unity.c +1300 -0
  17. data/tracks/c/exercises/allergies/test/vendor/unity.h +274 -0
  18. data/tracks/c/exercises/allergies/test/vendor/unity_internals.h +701 -0
  19. data/tracks/c/exercises/atbash-cipher/makefile +16 -0
  20. data/tracks/c/exercises/atbash-cipher/src/example.c +71 -0
  21. data/tracks/c/exercises/atbash-cipher/src/example.h +7 -0
  22. data/tracks/c/exercises/atbash-cipher/test/test_atbash_cipher.c +113 -0
  23. data/tracks/c/exercises/atbash-cipher/test/vendor/unity.c +1300 -0
  24. data/tracks/c/exercises/atbash-cipher/test/vendor/unity.h +274 -0
  25. data/tracks/c/exercises/atbash-cipher/test/vendor/unity_internals.h +701 -0
  26. data/tracks/c/exercises/phone-number/makefile +16 -0
  27. data/tracks/c/exercises/phone-number/src/example.c +66 -0
  28. data/tracks/c/exercises/phone-number/src/example.h +8 -0
  29. data/tracks/c/exercises/phone-number/test/test_phone_number.c +108 -0
  30. data/tracks/c/exercises/phone-number/test/vendor/unity.c +1300 -0
  31. data/tracks/c/exercises/phone-number/test/vendor/unity.h +274 -0
  32. data/tracks/c/exercises/phone-number/test/vendor/unity_internals.h +701 -0
  33. data/tracks/csharp/config.json +8 -0
  34. data/tracks/csharp/exercises/bowling/BowlingTest.cs +188 -33
  35. data/tracks/csharp/exercises/bowling/Example.cs +38 -9
  36. data/tracks/csharp/exercises/rectangles/Example.cs +91 -0
  37. data/tracks/csharp/exercises/rectangles/RectanglesTest.cs +133 -0
  38. data/tracks/elisp/docs/INSTALLATION.org +1 -1
  39. data/tracks/elixir/config.json +8 -66
  40. data/tracks/elixir/docs/LEARNING.md +1 -1
  41. data/tracks/elixir/exercises/diamond/diamond_test.exs +12 -12
  42. data/tracks/elixir/exercises/grep/example.exs +92 -0
  43. data/tracks/elixir/exercises/grep/grep.exs +6 -0
  44. data/tracks/elixir/exercises/grep/grep_test.exs +259 -0
  45. data/tracks/elixir/exercises/markdown/markdown.exs +59 -2
  46. data/tracks/elixir/exercises/nucleotide-count/nucleotide_count_test.exs +4 -4
  47. data/tracks/elixir/exercises/phone-number/phone_number_test.exs +5 -0
  48. data/tracks/fsharp/exercises/bowling/BowlingTest.fs +158 -43
  49. data/tracks/fsharp/exercises/bowling/Example.fs +53 -24
  50. data/tracks/go/config.json +5 -0
  51. data/tracks/go/exercises/diamond/diamond_test.go +227 -0
  52. data/tracks/go/exercises/diamond/example.go +47 -0
  53. data/tracks/go/exercises/food-chain/example.go +1 -1
  54. data/tracks/go/exercises/food-chain/food_chain_test.go +30 -6
  55. data/tracks/go/exercises/nucleotide-count/example.go +21 -8
  56. data/tracks/go/exercises/nucleotide-count/nucleotide_count_test.go +45 -37
  57. data/tracks/haskell/exercises/anagram/test/Tests.hs +1 -11
  58. data/tracks/java/bin/journey-test.sh +165 -128
  59. data/tracks/java/docs/ABOUT.md +5 -8
  60. data/tracks/java/exercises/hello-world/build.gradle +0 -6
  61. data/tracks/java/exercises/hello-world/src/test/java/HelloWorldTest.java +0 -1
  62. data/tracks/java/exercises/meetup/build.gradle +0 -1
  63. data/tracks/java/exercises/meetup/src/example/java/Meetup.java +9 -7
  64. data/tracks/java/exercises/meetup/src/test/java/MeetupTest.java +185 -188
  65. data/tracks/lua/config.json +0 -73
  66. data/tracks/lua/exercises/bowling/bowling_spec.lua +92 -48
  67. data/tracks/lua/exercises/bowling/example.lua +4 -1
  68. data/tracks/objective-c/config.json +9 -30
  69. data/tracks/objective-c/exercises/pangram/PangramExample.h +7 -0
  70. data/tracks/objective-c/exercises/pangram/PangramExample.m +21 -0
  71. data/tracks/objective-c/exercises/pangram/PangramTest.m +51 -0
  72. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +18 -0
  73. data/tracks/ocaml/README.md +46 -1
  74. data/tracks/ocaml/SETUP.md +21 -2
  75. data/tracks/ocaml/config.json +48 -78
  76. data/tracks/perl5/README.md +15 -8
  77. data/tracks/perl5/testall.pl +5 -5
  78. data/tracks/php/config.json +26 -34
  79. data/tracks/php/docs/ABOUT.md +15 -0
  80. data/tracks/php/exercises/allergies/allergies_test.php +121 -0
  81. data/tracks/php/exercises/allergies/example.php +64 -0
  82. data/tracks/php/exercises/etl/etl_test.php +52 -0
  83. data/tracks/php/exercises/etl/example.php +12 -0
  84. data/tracks/php/exercises/nucleotide-count/example.php +25 -0
  85. data/tracks/php/exercises/nucleotide-count/nucleotide-count_test.php +36 -0
  86. data/tracks/php/exercises/pig-latin/example.php +25 -29
  87. data/tracks/php/exercises/pig-latin/pig-latin_test.php +26 -19
  88. data/tracks/php/exercises/space-age/example.php +65 -0
  89. data/tracks/php/exercises/space-age/space-age_test.php +70 -0
  90. data/tracks/php/exercises/triangle/example.php +43 -0
  91. data/tracks/php/exercises/triangle/triangle_test.php +140 -0
  92. data/tracks/pony/exercises/anagram/example.pony +6 -6
  93. data/tracks/pony/exercises/anagram/test.pony +3 -4
  94. data/tracks/pony/exercises/bob/test.pony +23 -23
  95. data/tracks/pony/exercises/difference-of-squares/test.pony +11 -11
  96. data/tracks/pony/exercises/hamming/example.pony +3 -3
  97. data/tracks/pony/exercises/hamming/test.pony +16 -16
  98. data/tracks/pony/exercises/hello-world/test.pony +5 -4
  99. data/tracks/pony/exercises/leap/test.pony +8 -8
  100. data/tracks/python/config.json +18 -0
  101. data/tracks/python/exercises/diamond/diamond_test.py +33 -0
  102. data/tracks/python/exercises/diamond/example.py +15 -0
  103. data/tracks/python/exercises/linked-list/example.py +47 -0
  104. data/tracks/python/exercises/linked-list/linked_list.py +13 -0
  105. data/tracks/python/exercises/linked-list/linked_list_test.py +49 -0
  106. data/tracks/python/exercises/list-ops/example.py +55 -0
  107. data/tracks/python/exercises/list-ops/list_ops.py +38 -0
  108. data/tracks/python/exercises/list-ops/list_ops_test.py +136 -0
  109. data/tracks/ruby/bin/generate +22 -2
  110. data/tracks/ruby/config.json +12 -83
  111. data/tracks/ruby/exercises/allergies/allergies_test.rb +0 -1
  112. data/tracks/ruby/exercises/atbash-cipher/atbash_cipher_test.rb +0 -1
  113. data/tracks/ruby/exercises/beer-song/beer_song_test.rb +1 -2
  114. data/tracks/ruby/exercises/binary/example.rb +0 -1
  115. data/tracks/ruby/exercises/binary-search-tree/binary_search_tree_test.rb +1 -1
  116. data/tracks/ruby/exercises/bowling/.version +1 -0
  117. data/tracks/ruby/exercises/bowling/bowling_test.rb +109 -133
  118. data/tracks/ruby/exercises/bowling/example.rb +7 -7
  119. data/tracks/ruby/exercises/bowling/example.tt +27 -0
  120. data/tracks/ruby/exercises/circular-buffer/circular_buffer_test.rb +0 -2
  121. data/tracks/ruby/exercises/clock/example.rb +0 -2
  122. data/tracks/ruby/exercises/connect/connect_test.rb +0 -1
  123. data/tracks/ruby/exercises/custom-set/custom_set_test.rb +0 -1
  124. data/tracks/ruby/exercises/diamond/diamond_test.rb +0 -1
  125. data/tracks/ruby/exercises/etl/etl_test.rb +1 -1
  126. data/tracks/ruby/exercises/house/house_test.rb +0 -1
  127. data/tracks/ruby/exercises/isogram/isogram_test.rb +2 -2
  128. data/tracks/ruby/exercises/largest-series-product/example.tt +0 -3
  129. data/tracks/ruby/exercises/largest-series-product/largest_series_product_test.rb +0 -4
  130. data/tracks/ruby/exercises/linked-list/linked_list_test.rb +1 -1
  131. data/tracks/ruby/exercises/meetup/meetup_test.rb +0 -1
  132. data/tracks/ruby/exercises/nth-prime/example.tt +0 -2
  133. data/tracks/ruby/exercises/nth-prime/nth_prime_test.rb +0 -2
  134. data/tracks/ruby/exercises/ocr-numbers/ocr_numbers_test.rb +1 -2
  135. data/tracks/ruby/exercises/protein-translation/protein_translation_test.rb +0 -1
  136. data/tracks/ruby/exercises/proverb/proverb_test.rb +1 -3
  137. data/tracks/ruby/exercises/queen-attack/example.rb +3 -1
  138. data/tracks/ruby/exercises/queen-attack/queen_attack_test.rb +34 -8
  139. data/tracks/ruby/exercises/robot-simulator/robot_simulator_test.rb +1 -1
  140. data/tracks/ruby/exercises/strain/strain_test.rb +2 -2
  141. data/tracks/ruby/exercises/tournament/.version +1 -0
  142. data/tracks/ruby/exercises/tournament/example.rb +54 -0
  143. data/tracks/ruby/exercises/tournament/example.tt +23 -0
  144. data/tracks/ruby/exercises/tournament/tournament_test.rb +92 -0
  145. data/tracks/ruby/exercises/transpose/.version +1 -0
  146. data/tracks/ruby/exercises/transpose/example.rb +14 -0
  147. data/tracks/ruby/exercises/transpose/example.tt +22 -0
  148. data/tracks/ruby/exercises/transpose/transpose_test.rb +303 -0
  149. data/tracks/ruby/lib/bowling_cases.rb +46 -0
  150. data/tracks/ruby/lib/isogram_cases.rb +1 -1
  151. data/tracks/ruby/lib/tournament_cases.rb +45 -0
  152. data/tracks/ruby/lib/transpose_cases.rb +45 -0
  153. data/tracks/rust/config.json +2 -0
  154. data/tracks/rust/exercises/bowling/.gitignore +7 -0
  155. data/tracks/rust/exercises/bowling/Cargo.toml +3 -0
  156. data/tracks/rust/exercises/bowling/example.rs +134 -0
  157. data/tracks/rust/exercises/bowling/tests/bowling.rs +373 -0
  158. data/tracks/rust/exercises/grains/.gitignore +7 -0
  159. data/tracks/rust/exercises/grains/Cargo.toml +3 -0
  160. data/tracks/rust/exercises/grains/example.rs +11 -0
  161. data/tracks/rust/exercises/grains/src/lib.rs +7 -0
  162. data/tracks/rust/exercises/grains/tests/grains.rs +63 -0
  163. data/tracks/rust/problems.md +2 -0
  164. data/tracks/scala/README.md +38 -0
  165. data/tracks/scala/config.json +20 -74
  166. data/tracks/scala/exercises/accumulate/src/test/scala/accumulate_test.scala +4 -0
  167. data/tracks/scala/exercises/allergies/src/test/scala/allergies_test.scala +11 -0
  168. data/tracks/scala/exercises/alphametics/build.sbt +6 -0
  169. data/tracks/scala/exercises/alphametics/example.scala +125 -0
  170. data/tracks/scala/exercises/alphametics/src/main/scala/.keep +0 -0
  171. data/tracks/scala/exercises/alphametics/src/test/scala/AlphameticsTest.scala +62 -0
  172. data/tracks/scala/exercises/atbash-cipher/src/test/scala/atbash_test.scala +8 -0
  173. data/tracks/scala/exercises/bank-account/src/test/scala/BankAccountTest.scala +4 -0
  174. data/tracks/scala/exercises/binary/src/test/scala/binary_test.scala +13 -0
  175. data/tracks/scala/exercises/binary-search-tree/src/test/scala/BstTest.scala +11 -0
  176. data/tracks/scala/exercises/bowling/Example.scala +116 -0
  177. data/tracks/scala/exercises/bowling/build.sbt +3 -0
  178. data/tracks/scala/exercises/bowling/src/main/scala/Bowling.scala +11 -0
  179. data/tracks/scala/exercises/bowling/src/test/scala/BowlingSuite.scala +237 -0
  180. data/tracks/scala/exercises/clock/src/test/scala/ClockTest.scala +50 -0
  181. data/tracks/scala/exercises/connect/README.md +17 -0
  182. data/tracks/scala/exercises/connect/src/test/scala/ConnectTest.scala +7 -0
  183. data/tracks/scala/exercises/crypto-square/src/test/scala/{CrytpoSquareTest.scala → CryptoSquareTest.scala} +9 -0
  184. data/tracks/scala/exercises/custom-set/src/test/scala/CustomSetTest.scala +36 -0
  185. data/tracks/scala/exercises/difference-of-squares/src/test/scala/squares_test.scala +8 -0
  186. data/tracks/scala/exercises/forth/src/test/scala/ForthTest.scala +22 -0
  187. data/tracks/scala/exercises/hexadecimal/src/test/scala/HexadecimalTest.scala +8 -0
  188. data/tracks/scala/exercises/kindergarten-garden/src/test/scala/GardenTest.scala +5 -0
  189. data/tracks/scala/exercises/largest-series-product/src/test/scala/SeriesTest.scala +2 -0
  190. data/tracks/scala/exercises/linked-list/src/test/scala/DequeTest.scala +4 -0
  191. data/tracks/scala/exercises/luhn/src/test/scala/LuhnTest.scala +4 -0
  192. data/tracks/scala/exercises/matrix/src/test/scala/MatrixTest.scala +2 -0
  193. data/tracks/scala/exercises/minesweeper/src/test/scala/MinesweeperTest.scala +6 -0
  194. data/tracks/scala/exercises/nth-prime/src/test/scala/PrimeTest.scala +5 -0
  195. data/tracks/scala/exercises/ocr-numbers/src/test/scala/OcrTest.scala +15 -0
  196. data/tracks/scala/exercises/octal/src/test/scala/OctalTest.scala +7 -0
  197. data/tracks/scala/exercises/parallel-letter-frequency/src/test/scala/FrequencyTest.scala +8 -0
  198. data/tracks/scala/exercises/pascals-triangle/src/test/scala/PascalsTriangleTest.scala +5 -0
  199. data/tracks/scala/exercises/pig-latin/src/test/scala/PigLatinTest.scala +4 -0
  200. data/tracks/scala/exercises/pythagorean-triplet/src/test/scala/PythagoreanTripletTest.scala +3 -0
  201. data/tracks/scala/exercises/queen-attack/src/test/scala/QueensTest.scala +5 -0
  202. data/tracks/scala/exercises/robot-simulator/src/test/scala/RobotTest.scala +16 -8
  203. data/tracks/scala/exercises/say/src/test/scala/SayTest.scala +34 -17
  204. data/tracks/scala/exercises/scrabble-score/src/test/scala/scrabble_score_test.scala +6 -0
  205. data/tracks/scala/exercises/secret-handshake/src/test/scala/SecretHandshakeTest.scala +18 -9
  206. data/tracks/scala/exercises/series/src/test/scala/SeriesTest.scala +4 -2
  207. data/tracks/scala/exercises/sieve/src/test/scala/SieveTest.scala +8 -4
  208. data/tracks/scala/exercises/simple-cipher/src/test/scala/CipherTest.scala +17 -9
  209. data/tracks/scala/exercises/sublist/src/test/scala/sublist_test.scala +17 -0
  210. data/tracks/scala/exercises/trinary/src/test/scala/TrinaryTest.scala +14 -7
  211. data/tracks/scala/exercises/wordy/src/test/scala/WordProblemTest.scala +28 -14
  212. data/tracks/scala/project/Build.scala +3 -3
  213. data/tracks/scala/testgen/src/main/scala/BowlingTestGenerator.scala +57 -0
  214. data/tracks/sml/config.json +41 -6
  215. data/tracks/sml/exercises/flatten-array/example.sml +6 -0
  216. data/tracks/sml/exercises/flatten-array/test_flatten_array.sml +10 -0
  217. data/tracks/sml/exercises/nth-prime/example.sml +46 -0
  218. data/tracks/sml/exercises/nth-prime/test_nth_prime.sml +14 -0
  219. data/tracks/sml/exercises/raindrops/example.sml +9 -0
  220. data/tracks/sml/exercises/raindrops/raindrops.sml +2 -0
  221. data/tracks/sml/exercises/raindrops/test_raindrops.sml +95 -0
  222. data/tracks/swift/config.json +269 -328
  223. data/tracks/swift/exercises/pangram/PangramExample.swift +17 -0
  224. data/tracks/swift/exercises/pangram/PangramTest.swift +43 -0
  225. data/tracks/swift/xcodeProject/xSwift.xcodeproj/project.pbxproj +16 -0
  226. metadata +95 -3
@@ -659,6 +659,14 @@
659
659
  "Arrays"
660
660
  ]
661
661
  },
662
+ {
663
+ "slug": "rectangles",
664
+ "difficulty": 7,
665
+ "topics": [
666
+ "Parsing",
667
+ "Transforming"
668
+ ]
669
+ },
662
670
  {
663
671
  "slug": "wordy",
664
672
  "difficulty": 7,
@@ -1,75 +1,230 @@
1
- using NUnit.Framework;
1
+ using System.Collections.Generic;
2
+ using NUnit.Framework;
2
3
 
3
4
  public class BowlingTest
4
5
  {
5
6
  [Test]
6
- public void Gutter_game()
7
+ public void Should_be_able_to_score_a_game_with_all_zeros()
7
8
  {
8
- var game = new BowlingGame();
9
- RollMany(0, 20, game);
9
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
10
+ var game = RollMany(rolls, new BowlingGame());
10
11
  Assert.That(game.Score(), Is.EqualTo(0));
11
12
  }
12
13
 
13
14
  [Ignore("Remove to run test")]
14
15
  [Test]
15
- public void All_ones_game()
16
+ public void Should_be_able_to_score_a_game_with_no_strikes_or_spares()
16
17
  {
17
- var game = new BowlingGame();
18
- RollMany(1, 20, game);
19
- Assert.That(game.Score(), Is.EqualTo(20));
18
+ var rolls = new[] { 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6 };
19
+ var game = RollMany(rolls, new BowlingGame());
20
+ Assert.That(game.Score(), Is.EqualTo(90));
20
21
  }
21
22
 
22
23
  [Ignore("Remove to run test")]
23
24
  [Test]
24
- public void One_spare_game()
25
+ public void A_spare_followed_by_zeros_is_worth_ten_points()
25
26
  {
26
- var game = new BowlingGame();
27
- RollSpare(game);
28
- game.Roll(3);
29
- RollMany(0, 17, game);
27
+ var rolls = new[] { 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
28
+ var game = RollMany(rolls, new BowlingGame());
29
+ Assert.That(game.Score(), Is.EqualTo(10));
30
+ }
30
31
 
32
+ [Ignore("Remove to run test")]
33
+ [Test]
34
+ public void Points_scored_in_the_roll_after_a_spare_are_counted_twice()
35
+ {
36
+ var rolls = new[] { 6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
37
+ var game = RollMany(rolls, new BowlingGame());
31
38
  Assert.That(game.Score(), Is.EqualTo(16));
32
39
  }
33
40
 
34
41
  [Ignore("Remove to run test")]
35
42
  [Test]
36
- public void One_strike_game()
43
+ public void Consecutive_spares_each_get_a_one_roll_bonus()
44
+ {
45
+ var rolls = new[] { 5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
46
+ var game = RollMany(rolls, new BowlingGame());
47
+ Assert.That(game.Score(), Is.EqualTo(31));
48
+ }
49
+
50
+ [Ignore("Remove to run test")]
51
+ [Test]
52
+ public void A_spare_in_the_last_frame_gets_a_one_roll_bonus_that_is_counted_once()
53
+ {
54
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7 };
55
+ var game = RollMany(rolls, new BowlingGame());
56
+ Assert.That(game.Score(), Is.EqualTo(17));
57
+ }
58
+
59
+ [Ignore("Remove to run test")]
60
+ [Test]
61
+ public void A_strike_earns_ten_points_in_frame_with_a_single_roll()
62
+ {
63
+ var rolls = new[] { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
64
+ var game = RollMany(rolls, new BowlingGame());
65
+ Assert.That(game.Score(), Is.EqualTo(10));
66
+ }
67
+
68
+ [Ignore("Remove to run test")]
69
+ [Test]
70
+ public void Points_scored_in_the_two_rolls_after_a_strike_are_counted_twice_as_a_bonus()
71
+ {
72
+ var rolls = new[] { 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
73
+ var game = RollMany(rolls, new BowlingGame());
74
+ Assert.That(game.Score(), Is.EqualTo(26));
75
+ }
76
+
77
+ [Ignore("Remove to run test")]
78
+ [Test]
79
+ public void Consecutive_strikes_each_get_the_two_roll_bonus()
80
+ {
81
+ var rolls = new[] { 10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
82
+ var game = RollMany(rolls, new BowlingGame());
83
+ Assert.That(game.Score(), Is.EqualTo(81));
84
+ }
85
+
86
+ [Ignore("Remove to run test")]
87
+ [Test]
88
+ public void A_strike_in_the_last_frame_gets_a_two_roll_bonus_that_is_counted_once()
37
89
  {
38
- var game = new BowlingGame();
39
- RollStrike(game);
40
- game.Roll(3);
41
- game.Roll(4);
42
- RollMany(0, 16, game);
90
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1 };
91
+ var game = RollMany(rolls, new BowlingGame());
92
+ Assert.That(game.Score(), Is.EqualTo(18));
93
+ }
94
+
95
+ [Ignore("Remove to run test")]
96
+ [Test]
97
+ public void Rolling_a_spare_with_the_two_roll_bonus_does_not_get_a_bonus_roll()
98
+ {
99
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3 };
100
+ var game = RollMany(rolls, new BowlingGame());
101
+ Assert.That(game.Score(), Is.EqualTo(20));
102
+ }
43
103
 
44
- Assert.That(game.Score(), Is.EqualTo(24));
104
+ [Ignore("Remove to run test")]
105
+ [Test]
106
+ public void Strikes_with_the_two_roll_bonus_do_not_get_bonus_rolls()
107
+ {
108
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10 };
109
+ var game = RollMany(rolls, new BowlingGame());
110
+ Assert.That(game.Score(), Is.EqualTo(30));
45
111
  }
46
112
 
47
113
  [Ignore("Remove to run test")]
48
114
  [Test]
49
- public void Perfect_game()
115
+ public void A_strike_with_the_one_roll_bonus_after_a_spare_in_the_last_frame_does_not_get_a_bonus()
50
116
  {
51
- var game = new BowlingGame();
52
- RollMany(10, 12, game);
117
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10 };
118
+ var game = RollMany(rolls, new BowlingGame());
119
+ Assert.That(game.Score(), Is.EqualTo(20));
120
+ }
53
121
 
122
+ [Ignore("Remove to run test")]
123
+ [Test]
124
+ public void All_strikes_is_a_perfect_game()
125
+ {
126
+ var rolls = new[] { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 };
127
+ var game = RollMany(rolls, new BowlingGame());
54
128
  Assert.That(game.Score(), Is.EqualTo(300));
55
129
  }
56
130
 
57
- private static void RollMany(int pins, int count, BowlingGame game)
131
+ [Ignore("Remove to run test")]
132
+ [Test]
133
+ public void Rolls_can_not_score_negative_points()
58
134
  {
59
- for (var i = 0; i < count; i++)
60
- {
61
- game.Roll(pins);
62
- }
135
+ var rolls = new[] { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
136
+ var game = RollMany(rolls, new BowlingGame());
137
+ Assert.That(game.Score(), Is.Null);
138
+ }
139
+
140
+ [Ignore("Remove to run test")]
141
+ [Test]
142
+ public void A_roll_can_not_score_more_than_10_points()
143
+ {
144
+ var rolls = new[] { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
145
+ var game = RollMany(rolls, new BowlingGame());
146
+ Assert.That(game.Score(), Is.Null);
147
+ }
148
+
149
+ [Ignore("Remove to run test")]
150
+ [Test]
151
+ public void Two_rolls_in_a_frame_can_not_score_more_than_10_points()
152
+ {
153
+ var rolls = new[] { 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
154
+ var game = RollMany(rolls, new BowlingGame());
155
+ Assert.That(game.Score(), Is.Null);
63
156
  }
64
157
 
65
- private static void RollSpare(BowlingGame game)
158
+ [Ignore("Remove to run test")]
159
+ [Test]
160
+ public void Two_bonus_rolls_after_a_strike_in_the_last_frame_can_not_score_more_than_10_points()
161
+ {
162
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6 };
163
+ var game = RollMany(rolls, new BowlingGame());
164
+ Assert.That(game.Score(), Is.Null);
165
+ }
166
+
167
+ [Ignore("Remove to run test")]
168
+ [Test]
169
+ public void An_unstarted_game_can_not_be_scored()
66
170
  {
67
- game.Roll(5);
68
- game.Roll(5);
171
+ var rolls = new int[0];
172
+ var game = RollMany(rolls, new BowlingGame());
173
+ Assert.That(game.Score(), Is.Null);
69
174
  }
70
175
 
71
- private static void RollStrike(BowlingGame game)
176
+ [Ignore("Remove to run test")]
177
+ [Test]
178
+ public void An_incomplete_game_can_not_be_scored()
72
179
  {
73
- game.Roll(10);
180
+ var rolls = new[] { 0, 0 };
181
+ var game = RollMany(rolls, new BowlingGame());
182
+ Assert.That(game.Score(), Is.Null);
183
+ }
184
+
185
+ [Ignore("Remove to run test")]
186
+ [Test]
187
+ public void A_game_with_more_than_ten_frames_can_not_be_scored()
188
+ {
189
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
190
+ var game = RollMany(rolls, new BowlingGame());
191
+ Assert.That(game.Score(), Is.Null);
192
+ }
193
+
194
+ [Ignore("Remove to run test")]
195
+ [Test]
196
+ public void Bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated()
197
+ {
198
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10 };
199
+ var game = RollMany(rolls, new BowlingGame());
200
+ Assert.That(game.Score(), Is.Null);
201
+ }
202
+
203
+ [Ignore("Remove to run test")]
204
+ [Test]
205
+ public void Both_bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated()
206
+ {
207
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 };
208
+ var game = RollMany(rolls, new BowlingGame());
209
+ Assert.That(game.Score(), Is.Null);
210
+ }
211
+
212
+ [Ignore("Remove to run test")]
213
+ [Test]
214
+ public void Bonus_roll_for_a_spare_in_the_last_frame_must_be_rolled_before_score_can_be_calculated()
215
+ {
216
+ var rolls = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3 };
217
+ var game = RollMany(rolls, new BowlingGame());
218
+ Assert.That(game.Score(), Is.Null);
219
+ }
220
+
221
+ private static BowlingGame RollMany(IEnumerable<int> rolls, BowlingGame game)
222
+ {
223
+ foreach (var pins in rolls)
224
+ {
225
+ game.Roll(pins);
226
+ }
227
+
228
+ return game;
74
229
  }
75
230
  }
@@ -9,38 +9,67 @@ public class BowlingGame
9
9
 
10
10
  public void Roll(int pins) => rolls.Add(pins);
11
11
 
12
- public int Score()
12
+ public int? Score()
13
13
  {
14
14
  var score = 0;
15
15
  var frameIndex = 0;
16
16
 
17
- for (int i = 0; i < NumberOfFrames; i++)
17
+ for (var i = 1; i <= NumberOfFrames; i++)
18
18
  {
19
+ if (rolls.Count <= frameIndex)
20
+ {
21
+ return null;
22
+ }
23
+
19
24
  if (IsStrike(frameIndex))
20
25
  {
21
- score += 10 + StrikeBonus(frameIndex);
22
- frameIndex += 1;
26
+ if (rolls.Count <= frameIndex + 2)
27
+ {
28
+ return null;
29
+ }
30
+
31
+ var strikeBonus = StrikeBonus(frameIndex);
32
+ if (strikeBonus > MaximumFrameScore && !IsStrike(frameIndex + 1))
33
+ {
34
+ return null;
35
+ }
36
+
37
+ score += 10 + strikeBonus;
38
+ frameIndex += i == NumberOfFrames ? 3 : 1;
23
39
  }
24
40
  else if (IsSpare(frameIndex))
25
41
  {
42
+ if (rolls.Count <= frameIndex + 2)
43
+ {
44
+ return null;
45
+ }
46
+
26
47
  score += 10 + SpareBonus(frameIndex);
27
- frameIndex += 2;
48
+ frameIndex += i == NumberOfFrames ? 3 : 2;
28
49
  }
29
50
  else
30
51
  {
31
- score += SumOfPinsInFrame(frameIndex);
52
+ var frameScore = FrameScore(frameIndex);
53
+ if (frameScore < 0 || frameScore > 10)
54
+ {
55
+ return null;
56
+ }
57
+
58
+ score += frameScore;
32
59
  frameIndex += 2;
33
60
  }
34
61
  }
35
-
36
- return score;
62
+
63
+ return CorrectNumberOfRolls(frameIndex) ? score : (int?)null;
37
64
  }
38
65
 
66
+ private bool CorrectNumberOfRolls(int frameIndex) => frameIndex == rolls.Count;
67
+
39
68
  private bool IsStrike(int frameIndex) => rolls[frameIndex] == MaximumFrameScore;
40
69
  private bool IsSpare(int frameIndex) => rolls[frameIndex] + rolls[frameIndex + 1] == MaximumFrameScore;
41
70
 
42
71
  private int StrikeBonus(int frameIndex) => rolls[frameIndex + 1] + rolls[frameIndex + 2];
43
72
  private int SpareBonus(int frameIndex) => rolls[frameIndex + 2];
44
73
 
45
- private int SumOfPinsInFrame(int frameIndex) => rolls[frameIndex] + rolls[frameIndex + 1];
74
+ private int FrameScore(int frameIndex) => rolls[frameIndex] + rolls[frameIndex + 1];
46
75
  }
@@ -0,0 +1,91 @@
1
+ using System;
2
+ using System.Drawing;
3
+ using System.Linq;
4
+
5
+ public static class Rectangles
6
+ {
7
+ public static int Count(string[] rows)
8
+ {
9
+ var grid = ParseGrid(rows);
10
+ var corners = FindCorners(grid);
11
+ return corners.Sum(corner => RectangleForCorner(corner, corners, grid));
12
+ }
13
+
14
+ private static CellType[][] ParseGrid(string[] rows)
15
+ => rows.Select(row => row.Select(ParseCell).ToArray()).ToArray();
16
+
17
+ private static CellType ParseCell(char cell)
18
+ {
19
+ switch (cell)
20
+ {
21
+ case '+':
22
+ return CellType.Corner;
23
+ case '-':
24
+ return CellType.HorizontalLine;
25
+ case '|':
26
+ return CellType.VerticalLine;
27
+ case ' ':
28
+ return CellType.Empty;
29
+ default:
30
+ throw new ArgumentException();
31
+ }
32
+ }
33
+
34
+ private static int Rows(CellType[][] grid) => grid.Length;
35
+
36
+ private static int Cols(CellType[][] grid) => grid[0].Length;
37
+
38
+ private static CellType Cell(Point point, CellType[][] grid) => grid[point.Y][point.X];
39
+
40
+ private static Point[] FindCorners(CellType[][] grid) =>
41
+ Enumerable.Range(0, Rows(grid)).SelectMany(y =>
42
+ Enumerable.Range(0, Cols(grid)).Select(x => new Point(x, y)))
43
+ .Where(point => Cell(point, grid) == CellType.Corner)
44
+ .ToArray();
45
+
46
+ private static bool ConnectsVertically(Point point, CellType[][] grid) =>
47
+ (Cell(point, grid) == CellType.VerticalLine) ||
48
+ (Cell(point, grid) == CellType.Corner);
49
+
50
+ private static bool ConnectedVertically(Point top, Point bottom, CellType[][] grid) =>
51
+ Enumerable.Range(top.Y + 1, bottom.Y - top.Y - 1).All(y => ConnectsVertically(new Point(top.X, y), grid));
52
+
53
+ private static bool ConnectsHorizontally(Point point, CellType[][] grid) =>
54
+ (Cell(point, grid) == CellType.HorizontalLine) ||
55
+ (Cell(point, grid) == CellType.Corner);
56
+
57
+ private static bool ConnectedHorizontally(Point left, Point right, CellType[][] grid) =>
58
+ Enumerable.Range(left.X + 1, right.X - left.X - 1).All(x => ConnectsHorizontally(new Point(x, left.Y), grid));
59
+
60
+ private static bool IsTopLineOfRectangle(Point topLeft, Point topRight, CellType[][] grid) =>
61
+ (topRight.X > topLeft.X) && (topRight.Y == topLeft.Y) && ConnectedHorizontally(topLeft, topRight, grid);
62
+
63
+ private static bool IsRightLineOfRectangle(Point topRight, Point bottomRight, CellType[][] grid) =>
64
+ (bottomRight.X == topRight.X) && (bottomRight.Y > topRight.Y) &&
65
+ ConnectedVertically(topRight, bottomRight, grid);
66
+
67
+ private static bool IsBottomLineOfRectangle(Point bottomLeft, Point bottomRight, CellType[][] grid) =>
68
+ (bottomRight.X > bottomLeft.X) && (bottomRight.Y == bottomLeft.Y) &&
69
+ ConnectedHorizontally(bottomLeft, bottomRight, grid);
70
+
71
+ private static bool IsLeftLineOfRectangle(Point topLeft, Point bottomLeft, CellType[][] grid) =>
72
+ (bottomLeft.X == topLeft.X) && (bottomLeft.Y > topLeft.Y) && ConnectedVertically(topLeft, bottomLeft, grid);
73
+
74
+ private static int RectangleForCorner(Point topLeft, Point[] corners, CellType[][] grid)
75
+ {
76
+ return (from topRight in corners.Where(corner => IsTopLineOfRectangle(topLeft, corner, grid))
77
+ from bottomLeft in corners.Where(corner => IsLeftLineOfRectangle(topLeft, corner, grid))
78
+ from bottomRight in corners.Where(corner => IsRightLineOfRectangle(topRight, corner, grid) &&
79
+ IsBottomLineOfRectangle(bottomLeft, corner, grid))
80
+ select 1)
81
+ .Count();
82
+ }
83
+
84
+ private enum CellType
85
+ {
86
+ Empty,
87
+ Corner,
88
+ HorizontalLine,
89
+ VerticalLine
90
+ }
91
+ }
@@ -0,0 +1,133 @@
1
+ using NUnit.Framework;
2
+
3
+ public class RectanglesTest
4
+ {
5
+ [Test]
6
+ public void No_rows()
7
+ {
8
+ var input = new string[0];
9
+ Assert.That(Rectangles.Count(input), Is.EqualTo(0));
10
+ }
11
+
12
+ [Ignore("Remove to run test")]
13
+ [Test]
14
+ public void No_columns()
15
+ {
16
+ var input = new[] { "" };
17
+ Assert.That(Rectangles.Count(input), Is.EqualTo(0));
18
+ }
19
+
20
+ [Ignore("Remove to run test")]
21
+ [Test]
22
+ public void No_rectangles()
23
+ {
24
+ var input = new[] { " " };
25
+ Assert.That(Rectangles.Count(input), Is.EqualTo(0));
26
+ }
27
+
28
+ [Ignore("Remove to run test")]
29
+ [Test]
30
+ public void One_rectangle()
31
+ {
32
+ var input = new[]
33
+ {
34
+ "+-+",
35
+ "| |",
36
+ "+-+"
37
+ };
38
+ Assert.That(Rectangles.Count(input), Is.EqualTo(1));
39
+ }
40
+
41
+ [Ignore("Remove to run test")]
42
+ [Test]
43
+ public void Two_rectangles_without_shared_parts()
44
+ {
45
+ var input = new[]
46
+ {
47
+ " +-+",
48
+ " | |",
49
+ "+-+-+",
50
+ "| | ",
51
+ "+-+ "
52
+ };
53
+ Assert.That(Rectangles.Count(input), Is.EqualTo(2));
54
+ }
55
+
56
+ [Ignore("Remove to run test")]
57
+ [Test]
58
+ public void Five_rectangles_with_shared_parts()
59
+ {
60
+ var input = new[]
61
+ {
62
+ " +-+",
63
+ " | |",
64
+ "+-+-+",
65
+ "| | |",
66
+ "+-+-+"
67
+ };
68
+ Assert.That(Rectangles.Count(input), Is.EqualTo(5));
69
+ }
70
+
71
+ [Ignore("Remove to run test")]
72
+ [Test]
73
+ public void Only_complete_rectangles_are_counted()
74
+ {
75
+ var input = new[]
76
+ {
77
+ " +-+",
78
+ " |",
79
+ "+-+-+",
80
+ "| | -",
81
+ "+-+-+"
82
+ };
83
+ Assert.That(Rectangles.Count(input), Is.EqualTo(1));
84
+ }
85
+
86
+ [Ignore("Remove to run test")]
87
+ [Test]
88
+ public void Rectangles_can_be_of_different_sizes()
89
+ {
90
+ var input = new[]
91
+ {
92
+ "+------+----+",
93
+ "| | |",
94
+ "+---+--+ |",
95
+ "| | |",
96
+ "+---+-------+"
97
+ };
98
+ Assert.That(Rectangles.Count(input), Is.EqualTo(3));
99
+ }
100
+
101
+ [Ignore("Remove to run test")]
102
+ [Test]
103
+ public void Corner_is_required_for_a_rectangle_to_be_complete()
104
+ {
105
+ var input = new[]
106
+ {
107
+ "+------+----+",
108
+ "| | |",
109
+ "+------+ |",
110
+ "| | |",
111
+ "+---+-------+"
112
+ };
113
+ Assert.That(Rectangles.Count(input), Is.EqualTo(2));
114
+ }
115
+
116
+ [Ignore("Remove to run test")]
117
+ [Test]
118
+ public void Large_input_with_many_rectangles()
119
+ {
120
+ var input = new[]
121
+ {
122
+ "+---+--+----+",
123
+ "| +--+----+",
124
+ "+---+--+ |",
125
+ "| +--+----+",
126
+ "+---+--+--+-+",
127
+ "+---+--+--+-+",
128
+ "+------+ | |",
129
+ " +-+"
130
+ };
131
+ Assert.That(Rectangles.Count(input), Is.EqualTo(60));
132
+ }
133
+ }
@@ -43,7 +43,7 @@ manager or build from source as appropriate.
43
43
  *** Windows
44
44
  So you've decided to install Emacs on Windows.
45
45
 
46
- [[http:/www.zeldauniverse.net/wp-content/uploads/2012/01/83-Image-2.jpg]]
46
+ [[http://www.zeldauniverse.net/wp-content/uploads/2012/01/83-Image-2.jpg]]
47
47
 
48
48
  I've never done it, but the prevailing wisdom is that you just need to visit the
49
49
  [[http://ftp.wayne.edu/gnu/emacs/windows/][FTP archive]], grab the correct binary (=emacs-24.x-bin-xxx.zip=), unzip it and
@@ -3,72 +3,6 @@
3
3
  "language": "Elixir",
4
4
  "repository": "https://github.com/exercism/xelixir",
5
5
  "active": true,
6
- "problems": [
7
- "hello-world",
8
- "nucleotide-count",
9
- "space-age",
10
- "bob",
11
- "word-count",
12
- "accumulate",
13
- "acronym",
14
- "raindrops",
15
- "run-length-encoding",
16
- "sublist",
17
- "scrabble-score",
18
- "sum-of-multiples",
19
- "anagram",
20
- "bracket-push",
21
- "rna-transcription",
22
- "phone-number",
23
- "nth-prime",
24
- "roman-numerals",
25
- "hamming",
26
- "triangle",
27
- "beer-song",
28
- "isogram",
29
- "grade-school",
30
- "list-ops",
31
- "flatten-array",
32
- "leap",
33
- "kindergarten-garden",
34
- "etl",
35
- "meetup",
36
- "grains",
37
- "change",
38
- "parallel-letter-frequency",
39
- "binary",
40
- "luhn",
41
- "markdown",
42
- "gigasecond",
43
- "queen-attack",
44
- "pascals-triangle",
45
- "saddle-points",
46
- "hexadecimal",
47
- "diamond",
48
- "binary-search",
49
- "prime-factors",
50
- "sieve",
51
- "wordy",
52
- "robot-simulator",
53
- "atbash-cipher",
54
- "bank-account",
55
- "largest-series-product",
56
- "crypto-square",
57
- "pythagorean-triplet",
58
- "allergies",
59
- "palindrome-products",
60
- "rail-fence-cipher",
61
- "zipper",
62
- "minesweeper",
63
- "connect",
64
- "difference-of-squares",
65
- "bowling",
66
- "dot-dsl",
67
- "custom-set",
68
- "forth",
69
- "pangram",
70
- "clock"
71
- ],
72
6
  "exercises": [
73
7
  {
74
8
  "slug": "hello-world",
@@ -460,6 +394,14 @@
460
394
  "Transforming",
461
395
  "Integers"
462
396
  ]
397
+ },
398
+ {
399
+ "slug": "grep",
400
+ "difficulty": 1,
401
+ "topics": [
402
+ "Strings",
403
+ "Enumerations"
404
+ ]
463
405
  }
464
406
  ],
465
407
  "deprecated": [
@@ -2,7 +2,7 @@ Exercism provides exercises and feedback but can be difficult to jump into for t
2
2
 
3
3
  * [Elixir Getting Started Guide](http://elixir-lang.org/getting-started/introduction.html)
4
4
  * [Elixir Documentation](http://elixir-lang.org/docs/stable/elixir/)
5
- * [Programming Elixir](http://pragprog.com/book/elixir/programming-elixir), by Dave Thomas
5
+ * [Programming Elixir](https://pragprog.com/book/elixir13/programming-elixir-1-3), by Dave Thomas
6
6
  * [StackOverflow](http://stackoverflow.com/questions/tagged/elixir)
7
7
  * [Introducing Elixir](http://shop.oreilly.com/product/0636920030584.do), by Simon St. Laurent, J. David Eisenberg
8
8
  * [Etudes for Elixir](http://chimera.labs.oreilly.com/books/1234000001642), by J. David Eisenberg (exercise companion for Intro to Elixir)