trackler 2.0.0.1 → 2.0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
+ }