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
@@ -0,0 +1,303 @@
1
+ #!/usr/bin/env ruby
2
+ gem 'minitest', '>= 5.0.0'
3
+ require 'minitest/autorun'
4
+ require_relative 'transpose'
5
+
6
+ # Test data version:
7
+ # 0a51cfc
8
+ class TransposeTest < Minitest::Test
9
+ def test_empty_string
10
+ # skip
11
+ input = <<-INPUT.gsub(/^ {6}/, '')
12
+
13
+ INPUT
14
+ actual = Transpose.transpose(input)
15
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
16
+
17
+ EXPECTED
18
+ assert_equal expected.strip, actual
19
+ end
20
+
21
+ def test_two_characters_in_a_row
22
+ skip
23
+ input = <<-INPUT.gsub(/^ {6}/, '')
24
+ A1
25
+ INPUT
26
+ actual = Transpose.transpose(input)
27
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
28
+ A
29
+ 1
30
+ EXPECTED
31
+ assert_equal expected.strip, actual
32
+ end
33
+
34
+ def test_two_characters_in_a_column
35
+ skip
36
+ input = <<-INPUT.gsub(/^ {6}/, '')
37
+ A
38
+ 1
39
+ INPUT
40
+ actual = Transpose.transpose(input)
41
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
42
+ A1
43
+ EXPECTED
44
+ assert_equal expected.strip, actual
45
+ end
46
+
47
+ def test_simple
48
+ skip
49
+ input = <<-INPUT.gsub(/^ {6}/, '')
50
+ ABC
51
+ 123
52
+ INPUT
53
+ actual = Transpose.transpose(input)
54
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
55
+ A1
56
+ B2
57
+ C3
58
+ EXPECTED
59
+ assert_equal expected.strip, actual
60
+ end
61
+
62
+ def test_single_line
63
+ skip
64
+ input = <<-INPUT.gsub(/^ {6}/, '')
65
+ Single line.
66
+ INPUT
67
+ actual = Transpose.transpose(input)
68
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
69
+ S
70
+ i
71
+ n
72
+ g
73
+ l
74
+ e
75
+
76
+ l
77
+ i
78
+ n
79
+ e
80
+ .
81
+ EXPECTED
82
+ assert_equal expected.strip, actual
83
+ end
84
+
85
+ def test_first_line_longer_than_second_line
86
+ skip
87
+ input = <<-INPUT.gsub(/^ {6}/, '')
88
+ The fourth line.
89
+ The fifth line.
90
+ INPUT
91
+ actual = Transpose.transpose(input)
92
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
93
+ TT
94
+ hh
95
+ ee
96
+
97
+ ff
98
+ oi
99
+ uf
100
+ rt
101
+ th
102
+ h
103
+ l
104
+ li
105
+ in
106
+ ne
107
+ e.
108
+ .
109
+ EXPECTED
110
+ assert_equal expected.strip, actual
111
+ end
112
+
113
+ def test_second_line_longer_than_first_line
114
+ skip
115
+ input = <<-INPUT.gsub(/^ {6}/, '')
116
+ The first line.
117
+ The second line.
118
+ INPUT
119
+ actual = Transpose.transpose(input)
120
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
121
+ TT
122
+ hh
123
+ ee
124
+
125
+ fs
126
+ ie
127
+ rc
128
+ so
129
+ tn
130
+ d
131
+ l
132
+ il
133
+ ni
134
+ en
135
+ .e
136
+ .
137
+ EXPECTED
138
+ assert_equal expected.strip, actual
139
+ end
140
+
141
+ def test_square
142
+ skip
143
+ input = <<-INPUT.gsub(/^ {6}/, '')
144
+ HEART
145
+ EMBER
146
+ ABUSE
147
+ RESIN
148
+ TREND
149
+ INPUT
150
+ actual = Transpose.transpose(input)
151
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
152
+ HEART
153
+ EMBER
154
+ ABUSE
155
+ RESIN
156
+ TREND
157
+ EXPECTED
158
+ assert_equal expected.strip, actual
159
+ end
160
+
161
+ def test_rectangle
162
+ skip
163
+ input = <<-INPUT.gsub(/^ {6}/, '')
164
+ FRACTURE
165
+ OUTLINED
166
+ BLOOMING
167
+ SEPTETTE
168
+ INPUT
169
+ actual = Transpose.transpose(input)
170
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
171
+ FOBS
172
+ RULE
173
+ ATOP
174
+ CLOT
175
+ TIME
176
+ UNIT
177
+ RENT
178
+ EDGE
179
+ EXPECTED
180
+ assert_equal expected.strip, actual
181
+ end
182
+
183
+ def test_triangle
184
+ skip
185
+ input = <<-INPUT.gsub(/^ {6}/, '')
186
+ T
187
+ EE
188
+ AAA
189
+ SSSS
190
+ EEEEE
191
+ RRRRRR
192
+ INPUT
193
+ actual = Transpose.transpose(input)
194
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
195
+ TEASER
196
+ EASER
197
+ ASER
198
+ SER
199
+ ER
200
+ R
201
+ EXPECTED
202
+ assert_equal expected.strip, actual
203
+ end
204
+
205
+ def test_many_lines
206
+ skip
207
+ input = <<-INPUT.gsub(/^ {6}/, '')
208
+ Chor. Two households, both alike in dignity,
209
+ In fair Verona, where we lay our scene,
210
+ From ancient grudge break to new mutiny,
211
+ Where civil blood makes civil hands unclean.
212
+ From forth the fatal loins of these two foes
213
+ A pair of star-cross'd lovers take their life;
214
+ Whose misadventur'd piteous overthrows
215
+ Doth with their death bury their parents' strife.
216
+ The fearful passage of their death-mark'd love,
217
+ And the continuance of their parents' rage,
218
+ Which, but their children's end, naught could remove,
219
+ Is now the two hours' traffic of our stage;
220
+ The which if you with patient ears attend,
221
+ What here shall miss, our toil shall strive to mend.
222
+ INPUT
223
+ actual = Transpose.transpose(input)
224
+ expected = <<-EXPECTED.gsub(/^ {6}/, '')
225
+ CIFWFAWDTAWITW
226
+ hnrhr hohnhshh
227
+ o oeopotedi ea
228
+ rfmrmash cn t
229
+ .a e ie fthow
230
+ ia fr weh,whh
231
+ Trnco miae ie
232
+ w ciroitr btcr
233
+ oVivtfshfcuhhe
234
+ eeih a uote
235
+ hrnl sdtln is
236
+ oot ttvh tttfh
237
+ un bhaeepihw a
238
+ saglernianeoyl
239
+ e,ro -trsui ol
240
+ h uofcu sarhu
241
+ owddarrdan o m
242
+ lhg to'egccuwi
243
+ deemasdaeehris
244
+ sr als t ists
245
+ ,ebk 'phool'h,
246
+ reldi ffd
247
+ bweso tb rtpo
248
+ oea ileutterau
249
+ t kcnoorhhnatr
250
+ hl isvuyee'fi
251
+ atv es iisfet
252
+ ayoior trr ino
253
+ l lfsoh ecti
254
+ ion vedpn l
255
+ kuehtteieadoe
256
+ erwaharrar,fas
257
+ nekt te rh
258
+ ismdsehphnnosa
259
+ ncuse ra-tau l
260
+ et tormsural
261
+ dniuthwea'g t
262
+ iennwesnr hsts
263
+ g,ycoi tkrttet
264
+ n ,l r s'a anr
265
+ i ef 'dgcgdi
266
+ t aol eoe,v
267
+ y nei sl,u; e
268
+ , .sf to l
269
+ e rv d t
270
+ ; ie o
271
+ f, r
272
+ e e m
273
+ . m e
274
+ o n
275
+ v d
276
+ e .
277
+ ,
278
+ EXPECTED
279
+ assert_equal expected.strip, actual
280
+ end
281
+
282
+ # Problems in exercism evolve over time, as we find better ways to ask
283
+ # questions.
284
+ # The version number refers to the version of the problem you solved,
285
+ # not your solution.
286
+ #
287
+ # Define a constant named VERSION inside of the top level BookKeeping
288
+ # module, which may be placed near the end of your file.
289
+ #
290
+ # In your file, it will look like this:
291
+ #
292
+ # module BookKeeping
293
+ # VERSION = 1 # Where the version number matches the one in the test.
294
+ # end
295
+ #
296
+ # If you are curious, read more about constants on RubyDoc:
297
+ # http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
298
+
299
+ def test_bookkeeping
300
+ skip
301
+ assert_equal 1, BookKeeping::VERSION
302
+ end
303
+ end
@@ -0,0 +1,46 @@
1
+ class BowlingCase < OpenStruct
2
+ def test_name
3
+ "test_#{description.downcase.tr(' ', '_')}"
4
+ end
5
+
6
+ def skipped
7
+ index.zero? ? '# skip' : 'skip'
8
+ end
9
+
10
+ def work_load
11
+ indent_lines(assert)
12
+ end
13
+
14
+ private
15
+
16
+ def roll
17
+ "roll(#{rolls})"
18
+ end
19
+
20
+ def assert
21
+ if assert_error?
22
+ [
23
+ 'assert_raises StandardError do',
24
+ " #{roll}",
25
+ ' @game.score',
26
+ 'end'
27
+ ]
28
+ else
29
+ [roll, "assert_equal #{expected}, @game.score"]
30
+ end
31
+ end
32
+
33
+ def assert_error?
34
+ expected == -1
35
+ end
36
+
37
+ def indent_lines(code)
38
+ code.join("\n" + ' ' * 4)
39
+ end
40
+ end
41
+
42
+ BowlingCases = proc do |data|
43
+ JSON.parse(data)['score']['cases'].map.with_index do |row, i|
44
+ BowlingCase.new(row.merge('index' => i))
45
+ end
46
+ end
@@ -13,7 +13,7 @@ class IsogramCase < OpenStruct
13
13
  end
14
14
 
15
15
  def skip
16
- 'skip' unless index.zero?
16
+ index.zero? ? '# skip' : 'skip'
17
17
  end
18
18
  end
19
19
 
@@ -0,0 +1,45 @@
1
+ class TournamentCase < OpenStruct
2
+ def test_name
3
+ "test_#{description.tr(' ', '_').tr('()', '')}"
4
+ end
5
+
6
+ def skipped
7
+ index.zero? ? '# skip' : 'skip'
8
+ end
9
+
10
+ def workload
11
+ 'Tournament.tally(input)'
12
+ end
13
+
14
+ def expect
15
+ indented_heredoc(expected, 'TALLY')
16
+ end
17
+
18
+ def input_text
19
+ indented_heredoc(input, 'INPUT')
20
+ end
21
+
22
+ private
23
+
24
+ def indented_heredoc(string, delimiter)
25
+ [
26
+ "<<-#{delimiter}.gsub(/^ */, '')",
27
+ indent_lines(string),
28
+ indent_line(delimiter)
29
+ ].join("\n")
30
+ end
31
+
32
+ def indent_lines(lines, indent = 3)
33
+ lines.map { |line| indent_line(line, indent) }.join("\n")
34
+ end
35
+
36
+ def indent_line(line, indent = 2)
37
+ ' ' * indent * 2 + line
38
+ end
39
+ end
40
+
41
+ TournamentCases = proc do |data|
42
+ JSON.parse(data)['valid_inputs']['cases'].map.with_index do |row, i|
43
+ TournamentCase.new(row.merge('index' => i))
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ class TransposeCase < OpenStruct
2
+ def test_name
3
+ "test_#{description.tr(' ', '_')}"
4
+ end
5
+
6
+ def skipped
7
+ index.zero? ? '# skip' : 'skip'
8
+ end
9
+
10
+ def workload
11
+ 'Transpose.transpose(input)'
12
+ end
13
+
14
+ def expect
15
+ indented_heredoc(expected, 'EXPECTED')
16
+ end
17
+
18
+ def input_text
19
+ indented_heredoc(input, 'INPUT')
20
+ end
21
+
22
+ private
23
+
24
+ def indented_heredoc(string, delimiter)
25
+ [
26
+ "<<-#{delimiter}.gsub(/^ {6}/, '')",
27
+ indent_lines(string),
28
+ indent_line(delimiter)
29
+ ].join("\n")
30
+ end
31
+
32
+ def indent_lines(lines, indent = 3)
33
+ lines.map { |line| indent_line(line, indent) }.join("\n")
34
+ end
35
+
36
+ def indent_line(line, indent = 2)
37
+ ' ' * indent * 2 + line
38
+ end
39
+ end
40
+
41
+ TransposeCases = proc do |data|
42
+ JSON.parse(data)['cases'].map.with_index do |row, i|
43
+ TransposeCase.new(row.merge('index' => i))
44
+ end
45
+ end
@@ -11,6 +11,7 @@
11
11
  "bob",
12
12
  "beer-song",
13
13
  "difference-of-squares",
14
+ "grains",
14
15
  "hamming",
15
16
  "pascals-triangle",
16
17
  "scrabble-score",
@@ -29,6 +30,7 @@
29
30
  "robot-simulator",
30
31
  "bracket-push",
31
32
  "queen-attack",
33
+ "bowling",
32
34
  "sublist",
33
35
  "space-age",
34
36
  "allergies",
@@ -0,0 +1,7 @@
1
+ # Generated by Cargo
2
+ # will have compiled files and executables
3
+ /target/
4
+
5
+ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6
+ # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
7
+ Cargo.lock
@@ -0,0 +1,3 @@
1
+ [package]
2
+ name = "bowling"
3
+ version = "0.0.0"
@@ -0,0 +1,134 @@
1
+
2
+ pub struct BowlingGame {
3
+ frames: Vec<Frame>,
4
+ }
5
+
6
+ struct Frame {
7
+ rolls: Vec<u16>,
8
+ bonus: Vec<u16>,
9
+ }
10
+
11
+ impl Frame {
12
+ fn score(&self) -> u16 {
13
+ self.roll_score() + self.bonus_score()
14
+ }
15
+
16
+ fn roll_score(&self) -> u16 {
17
+ self.rolls.iter().sum()
18
+ }
19
+
20
+ fn bonus_score(&self) -> u16 {
21
+ self.bonus.iter().sum()
22
+ }
23
+
24
+ fn is_valid(&self) -> bool {
25
+ self.rolls_valid() && self.bonus_valid()
26
+ }
27
+
28
+ fn rolls_valid(&self) -> bool {
29
+ self.roll_score() <= 10
30
+ }
31
+
32
+ fn bonus_valid(&self) -> bool {
33
+ if self.is_open() || !self.bonus_done() {
34
+ return true;
35
+ }
36
+
37
+ if self.is_spare() {
38
+ return self.bonus_score() <= 10;
39
+ }
40
+
41
+ if let Some(first) = self.bonus.iter().next() {
42
+ if *first == 10 {
43
+ self.bonus_score() <= 20
44
+ } else {
45
+ self.bonus_score() <= 10
46
+ }
47
+ } else {
48
+ unreachable!();
49
+ }
50
+ }
51
+
52
+ fn is_complete(&self) -> bool {
53
+ self.is_open() || self.bonus_done()
54
+ }
55
+
56
+ fn rolls_done(&self) -> bool {
57
+ self.rolls.len() == 2 || self.is_strike()
58
+ }
59
+
60
+ fn bonus_done(&self) -> bool {
61
+ (self.is_spare() && self.bonus.len() == 1) || (self.is_strike() && self.bonus.len() == 2)
62
+ }
63
+
64
+ fn is_open(&self) -> bool {
65
+ self.rolls.len() == 2 && self.roll_score() < 10
66
+ }
67
+
68
+ fn is_spare(&self) -> bool {
69
+ self.rolls.len() == 2 && self.roll_score() == 10
70
+ }
71
+
72
+ fn is_strike(&self) -> bool {
73
+ self.rolls.len() == 1 && self.roll_score() == 10
74
+ }
75
+
76
+ fn add_roll(&mut self, roll: u16) {
77
+ if !self.is_complete() {
78
+ if self.is_spare() || self.is_strike() {
79
+ self.bonus.push(roll)
80
+ } else {
81
+ self.rolls.push(roll)
82
+ }
83
+ }
84
+ }
85
+
86
+ fn new() -> Self {
87
+ Frame {
88
+ rolls: vec![],
89
+ bonus: vec![],
90
+ }
91
+ }
92
+ }
93
+
94
+ impl BowlingGame {
95
+ pub fn new() -> Self {
96
+ BowlingGame { frames: vec![Frame::new()] }
97
+ }
98
+
99
+ pub fn roll(&mut self, pins: u16) -> Result<(), &'static str> {
100
+ if pins > 10 {
101
+ Err("Greater than 10 pins")
102
+ } else {
103
+ if self.score().is_ok() {
104
+ return Err("Game Finished. No more rolls.");
105
+ }
106
+
107
+ for mut frame in self.frames.iter_mut() {
108
+ frame.add_roll(pins)
109
+ }
110
+
111
+ if self.frames.iter().any(|f| !f.is_valid()) {
112
+ return Err("Invalid Roll");
113
+ }
114
+
115
+ if self.frames.iter().last().unwrap().rolls_done() && self.frames.len() < 10 {
116
+ self.frames.push(Frame::new());
117
+ }
118
+
119
+ Ok(())
120
+ }
121
+ }
122
+
123
+ pub fn score(&self) -> Result<u16, &'static str> {
124
+ if !self.is_done() {
125
+ Err("Game Incomplete")
126
+ } else {
127
+ Ok(self.frames.iter().fold(0, |acc, r| acc + r.score()))
128
+ }
129
+ }
130
+
131
+ fn is_done(&self) -> bool {
132
+ self.frames.len() == 10 && self.frames.iter().all(|f| f.is_complete())
133
+ }
134
+ }