trackler 2.2.1.54 → 2.2.1.55

Sign up to get free protection for your applications and to get access to all the features.
Files changed (280) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/dominoes/description.md +3 -3
  4. data/problem-specifications/exercises/two-fer/description.md +0 -28
  5. data/tracks/c/config.json +12 -0
  6. data/tracks/c/exercises/queen-attack/README.md +65 -0
  7. data/tracks/c/exercises/queen-attack/makefile +15 -0
  8. data/tracks/c/exercises/queen-attack/src/example.c +25 -0
  9. data/tracks/c/exercises/queen-attack/src/queen_attack.h +19 -0
  10. data/tracks/c/exercises/queen-attack/test/test_queen_attack.c +190 -0
  11. data/tracks/c/exercises/queen-attack/test/vendor/unity.c +1300 -0
  12. data/tracks/c/exercises/queen-attack/test/vendor/unity.h +274 -0
  13. data/tracks/c/exercises/queen-attack/test/vendor/unity_internals.h +701 -0
  14. data/tracks/common-lisp/exercises/acronym/README.md +1 -1
  15. data/tracks/delphi/exercises/two-fer/README.md +0 -28
  16. data/tracks/ecmascript/config.json +41 -0
  17. data/tracks/ecmascript/exercises/accumulate/package.json +5 -3
  18. data/tracks/ecmascript/exercises/acronym/package.json +5 -3
  19. data/tracks/ecmascript/exercises/all-your-base/package.json +5 -3
  20. data/tracks/ecmascript/exercises/allergies/package.json +5 -3
  21. data/tracks/ecmascript/exercises/alphametics/package.json +5 -3
  22. data/tracks/ecmascript/exercises/anagram/package.json +5 -3
  23. data/tracks/ecmascript/exercises/atbash-cipher/package.json +5 -3
  24. data/tracks/ecmascript/exercises/beer-song/package.json +5 -3
  25. data/tracks/ecmascript/exercises/binary-search-tree/package.json +5 -3
  26. data/tracks/ecmascript/exercises/binary-search/package.json +5 -3
  27. data/tracks/ecmascript/exercises/binary/package.json +5 -3
  28. data/tracks/ecmascript/exercises/bob/package.json +5 -3
  29. data/tracks/ecmascript/exercises/bowling/package.json +2 -2
  30. data/tracks/ecmascript/exercises/bracket-push/package.json +5 -3
  31. data/tracks/ecmascript/exercises/change/README.md +44 -0
  32. data/tracks/ecmascript/exercises/change/change.spec.js +80 -0
  33. data/tracks/ecmascript/exercises/change/example.js +120 -0
  34. data/tracks/ecmascript/exercises/change/package.json +69 -0
  35. data/tracks/ecmascript/exercises/circular-buffer/package.json +5 -3
  36. data/tracks/ecmascript/exercises/clock/package.json +5 -3
  37. data/tracks/ecmascript/exercises/collatz-conjecture/package.json +6 -4
  38. data/tracks/ecmascript/exercises/connect/package.json +5 -3
  39. data/tracks/ecmascript/exercises/crypto-square/package.json +5 -3
  40. data/tracks/ecmascript/exercises/custom-set/package.json +5 -3
  41. data/tracks/ecmascript/exercises/diamond/package.json +5 -3
  42. data/tracks/ecmascript/exercises/difference-of-squares/package.json +5 -3
  43. data/tracks/ecmascript/exercises/diffie-hellman/package.json +5 -3
  44. data/tracks/ecmascript/exercises/etl/package.json +5 -3
  45. data/tracks/ecmascript/exercises/flatten-array/package.json +5 -3
  46. data/tracks/ecmascript/exercises/food-chain/package.json +5 -3
  47. data/tracks/ecmascript/exercises/gigasecond/package.json +5 -3
  48. data/tracks/ecmascript/exercises/grade-school/package.json +5 -3
  49. data/tracks/ecmascript/exercises/grains/package.json +5 -3
  50. data/tracks/ecmascript/exercises/hamming/package.json +5 -3
  51. data/tracks/ecmascript/exercises/hello-world/package.json +5 -3
  52. data/tracks/ecmascript/exercises/hexadecimal/package.json +5 -3
  53. data/tracks/ecmascript/exercises/isbn-verifier/README.md +62 -0
  54. data/tracks/ecmascript/exercises/isbn-verifier/example.js +17 -0
  55. data/tracks/ecmascript/exercises/isbn-verifier/isbn-verifier.spec.js +81 -0
  56. data/tracks/ecmascript/exercises/isbn-verifier/package.json +71 -0
  57. data/tracks/ecmascript/exercises/isogram/package.json +5 -3
  58. data/tracks/ecmascript/exercises/kindergarten-garden/package.json +5 -3
  59. data/tracks/ecmascript/exercises/largest-series-product/package.json +5 -3
  60. data/tracks/ecmascript/exercises/leap/package.json +5 -3
  61. data/tracks/ecmascript/exercises/linked-list/package.json +5 -3
  62. data/tracks/ecmascript/exercises/list-ops/package.json +5 -3
  63. data/tracks/ecmascript/exercises/luhn/package.json +5 -3
  64. data/tracks/ecmascript/exercises/matrix/package.json +5 -3
  65. data/tracks/ecmascript/exercises/meetup/package.json +5 -3
  66. data/tracks/ecmascript/exercises/minesweeper/package.json +5 -3
  67. data/tracks/ecmascript/exercises/nth-prime/package.json +5 -3
  68. data/tracks/ecmascript/exercises/ocr-numbers/package.json +5 -3
  69. data/tracks/ecmascript/exercises/octal/package.json +5 -3
  70. data/tracks/ecmascript/exercises/palindrome-products/package.json +5 -3
  71. data/tracks/ecmascript/exercises/pangram/package.json +5 -3
  72. data/tracks/ecmascript/exercises/pascals-triangle/package.json +5 -3
  73. data/tracks/ecmascript/exercises/perfect-numbers/package.json +5 -3
  74. data/tracks/ecmascript/exercises/phone-number/package.json +5 -3
  75. data/tracks/ecmascript/exercises/pig-latin/package.json +5 -3
  76. data/tracks/ecmascript/exercises/prime-factors/package.json +5 -3
  77. data/tracks/ecmascript/exercises/proverb/package.json +5 -3
  78. data/tracks/ecmascript/exercises/pythagorean-triplet/package.json +5 -3
  79. data/tracks/ecmascript/exercises/queen-attack/package.json +5 -3
  80. data/tracks/ecmascript/exercises/raindrops/package.json +5 -3
  81. data/tracks/ecmascript/exercises/rna-transcription/package.json +5 -3
  82. data/tracks/ecmascript/exercises/robot-name/package.json +5 -3
  83. data/tracks/ecmascript/exercises/robot-simulator/package.json +5 -3
  84. data/tracks/ecmascript/exercises/roman-numerals/package.json +5 -3
  85. data/tracks/ecmascript/exercises/run-length-encoding/package.json +5 -3
  86. data/tracks/ecmascript/exercises/saddle-points/package.json +5 -3
  87. data/tracks/ecmascript/exercises/say/package.json +5 -3
  88. data/tracks/ecmascript/exercises/scrabble-score/package.json +5 -3
  89. data/tracks/ecmascript/exercises/secret-handshake/package.json +5 -3
  90. data/tracks/ecmascript/exercises/series/package.json +5 -3
  91. data/tracks/ecmascript/exercises/sieve/package.json +5 -3
  92. data/tracks/ecmascript/exercises/simple-cipher/package.json +5 -3
  93. data/tracks/ecmascript/exercises/simple-linked-list/package.json +5 -3
  94. data/tracks/ecmascript/exercises/space-age/package.json +5 -3
  95. data/tracks/ecmascript/exercises/strain/package.json +5 -3
  96. data/tracks/ecmascript/exercises/sublist/package.json +5 -3
  97. data/tracks/ecmascript/exercises/sum-of-multiples/package.json +5 -3
  98. data/tracks/ecmascript/exercises/transpose/README.md +94 -0
  99. data/tracks/ecmascript/exercises/transpose/example.js +12 -0
  100. data/tracks/ecmascript/exercises/transpose/package.json +71 -0
  101. data/tracks/ecmascript/exercises/transpose/transpose.spec.js +67 -0
  102. data/tracks/ecmascript/exercises/triangle/package.json +5 -3
  103. data/tracks/ecmascript/exercises/trinary/package.json +5 -3
  104. data/tracks/ecmascript/exercises/twelve-days/package.json +5 -3
  105. data/tracks/ecmascript/exercises/two-bucket/package.json +5 -3
  106. data/tracks/ecmascript/exercises/two-fer/package.json +5 -3
  107. data/tracks/ecmascript/exercises/word-count/package.json +5 -3
  108. data/tracks/ecmascript/exercises/word-search/package.json +5 -3
  109. data/tracks/ecmascript/exercises/wordy/package.json +5 -3
  110. data/tracks/ecmascript/package-lock.json +6219 -0
  111. data/tracks/ecmascript/package.json +5 -3
  112. data/tracks/erlang/exercises/collatz-conjecture/src/collatz_conjecture.erl +3 -4
  113. data/tracks/erlang/exercises/collatz-conjecture/src/example.erl +3 -3
  114. data/tracks/erlang/exercises/collatz-conjecture/test/collatz_conjecture_tests.erl +13 -9
  115. data/tracks/erlang/exercises/hello-world/src/hello_world.erl +2 -2
  116. data/tracks/erlang/exercises/leap/src/example.erl +1 -1
  117. data/tracks/erlang/exercises/leap/src/leap.erl +3 -3
  118. data/tracks/erlang/exercises/leap/test/leap_tests.erl +9 -9
  119. data/tracks/erlang/testgen/src/testgen.erl +16 -13
  120. data/tracks/erlang/testgen/src/tgen.erl +65 -38
  121. data/tracks/erlang/testgen/src/tgen_collatz-conjecture.erl +38 -0
  122. data/tracks/erlang/testgen/src/tgen_hello-world.erl +11 -19
  123. data/tracks/erlang/testgen/src/tgen_leap.erl +31 -0
  124. data/tracks/erlang/testgen/src/tgs.erl +80 -0
  125. data/tracks/fsharp/exercises/alphametics/AlphameticsTest.fs +78 -23
  126. data/tracks/fsharp/exercises/anagram/AnagramTest.fs +66 -34
  127. data/tracks/fsharp/exercises/connect/ConnectTest.fs +81 -68
  128. data/tracks/fsharp/exercises/connect/Example.fs +9 -5
  129. data/tracks/fsharp/exercises/food-chain/Example.fs +5 -9
  130. data/tracks/fsharp/exercises/food-chain/FoodChain.fs +2 -2
  131. data/tracks/fsharp/exercises/food-chain/FoodChainTest.fs +143 -75
  132. data/tracks/fsharp/exercises/hamming/Example.fs +8 -4
  133. data/tracks/fsharp/exercises/hamming/Hamming.fs +1 -1
  134. data/tracks/fsharp/exercises/hamming/HammingTest.fs +53 -13
  135. data/tracks/fsharp/exercises/house/Example.fs +5 -6
  136. data/tracks/fsharp/exercises/house/House.fs +3 -1
  137. data/tracks/fsharp/exercises/house/HouseTest.fs +272 -96
  138. data/tracks/fsharp/exercises/meetup/Example.fs +1 -1
  139. data/tracks/fsharp/exercises/meetup/Meetup.fs +1 -1
  140. data/tracks/fsharp/exercises/meetup/MeetupTest.fs +384 -73
  141. data/tracks/fsharp/exercises/ocr-numbers/Example.fs +43 -35
  142. data/tracks/fsharp/exercises/ocr-numbers/OcrNumbersTest.fs +160 -125
  143. data/tracks/fsharp/exercises/two-fer/Example.fs +4 -2
  144. data/tracks/fsharp/exercises/two-fer/TwoFer.fs +1 -1
  145. data/tracks/fsharp/exercises/two-fer/TwoFerTest.fs +7 -4
  146. data/tracks/fsharp/generators/Common.fs +6 -2
  147. data/tracks/fsharp/generators/Exercise.fs +14 -13
  148. data/tracks/fsharp/generators/Generators.fs +145 -2
  149. data/tracks/fsharp/generators/Options.fs +4 -6
  150. data/tracks/fsharp/generators/Output.fs +2 -2
  151. data/tracks/fsharp/generators/Program.fs +4 -3
  152. data/tracks/java/exercises/saddle-points/README.md +1 -1
  153. data/tracks/java/exercises/two-fer/README.md +0 -28
  154. data/tracks/javascript/exercises/beer-song/example.js +18 -14
  155. data/tracks/kotlin/exercises/saddle-points/README.md +1 -1
  156. data/tracks/kotlin/exercises/two-fer/README.md +0 -28
  157. data/tracks/lua/config.json +12 -0
  158. data/tracks/lua/exercises/collatz-conjecture/README.md +43 -0
  159. data/tracks/lua/exercises/collatz-conjecture/collatz-conjecture_spec.lua +33 -0
  160. data/tracks/lua/exercises/collatz-conjecture/example.lua +16 -0
  161. data/tracks/python/config.json +4 -1
  162. data/tracks/python/exercises/binary-search/binary_search_test.py +2 -0
  163. data/tracks/python/exercises/change/change_test.py +2 -0
  164. data/tracks/python/exercises/circular-buffer/circular_buffer_test.py +56 -50
  165. data/tracks/python/exercises/forth/example.py +3 -1
  166. data/tracks/python/exercises/forth/forth_test.py +43 -26
  167. data/tracks/python/exercises/nth-prime/nth_prime.py +1 -1
  168. data/tracks/python/exercises/rna-transcription/README.md +5 -0
  169. data/tracks/python/exercises/rna-transcription/example.py +1 -1
  170. data/tracks/python/exercises/rna-transcription/rna_transcription_test.py +7 -4
  171. data/tracks/python/exercises/robot-simulator/robot_simulator_test.py +9 -7
  172. data/tracks/python/exercises/saddle-points/saddle_points_test.py +15 -5
  173. data/tracks/python/exercises/simple-cipher/simple_cipher.py +7 -1
  174. data/tracks/python/exercises/word-count/example.py +6 -4
  175. data/tracks/python/exercises/word-count/word_count_test.py +49 -22
  176. data/tracks/python/exercises/word-search/word_search_test.py +104 -12
  177. data/tracks/rust/.travis.yml +2 -0
  178. data/tracks/rust/README.md +5 -0
  179. data/tracks/rust/_test/check-exercises.sh +0 -6
  180. data/tracks/rust/_test/ensure-lib-src-rs-exist.sh +19 -0
  181. data/tracks/rust/_test/ensure-stubs-compile.sh +26 -0
  182. data/tracks/rust/config.json +12 -0
  183. data/tracks/rust/config/exercise-readme-insert.md +3 -2
  184. data/tracks/rust/docs/ABOUT.md +2 -2
  185. data/tracks/rust/docs/LEARNING.md +1 -1
  186. data/tracks/rust/docs/RESOURCES.md +1 -1
  187. data/tracks/rust/docs/TESTS.md +2 -2
  188. data/tracks/rust/exercises/accumulate/README.md +3 -2
  189. data/tracks/rust/exercises/acronym/README.md +3 -2
  190. data/tracks/rust/exercises/all-your-base/README.md +3 -2
  191. data/tracks/rust/exercises/allergies/README.md +3 -2
  192. data/tracks/rust/exercises/alphametics/README.md +3 -2
  193. data/tracks/rust/exercises/anagram/README.md +3 -2
  194. data/tracks/rust/exercises/atbash-cipher/README.md +3 -2
  195. data/tracks/rust/exercises/beer-song/README.md +3 -2
  196. data/tracks/rust/exercises/beer-song/src/lib.rs +2 -2
  197. data/tracks/rust/exercises/binary-search/README.md +3 -2
  198. data/tracks/rust/exercises/bob/README.md +3 -2
  199. data/tracks/rust/exercises/bob/src/lib.rs +1 -1
  200. data/tracks/rust/exercises/bowling/README.md +3 -2
  201. data/tracks/rust/exercises/bracket-push/HINTS.md +1 -1
  202. data/tracks/rust/exercises/bracket-push/README.md +4 -3
  203. data/tracks/rust/exercises/circular-buffer/README.md +3 -2
  204. data/tracks/rust/exercises/clock/README.md +3 -2
  205. data/tracks/rust/exercises/collatz-conjecture/README.md +3 -2
  206. data/tracks/rust/exercises/collatz-conjecture/src/lib.rs +1 -1
  207. data/tracks/rust/exercises/crypto-square/README.md +3 -2
  208. data/tracks/rust/exercises/custom-set/README.md +3 -2
  209. data/tracks/rust/exercises/decimal/.meta/ALLOWED_TO_NOT_COMPILE +2 -0
  210. data/tracks/rust/exercises/decimal/README.md +3 -2
  211. data/tracks/rust/exercises/difference-of-squares/README.md +3 -2
  212. data/tracks/rust/exercises/difference-of-squares/src/lib.rs +3 -3
  213. data/tracks/rust/exercises/dominoes/README.md +3 -2
  214. data/tracks/rust/exercises/etl/README.md +3 -2
  215. data/tracks/rust/exercises/forth/README.md +3 -2
  216. data/tracks/rust/exercises/forth/src/lib.rs +3 -0
  217. data/tracks/rust/exercises/gigasecond/README.md +3 -2
  218. data/tracks/rust/exercises/grade-school/README.md +3 -2
  219. data/tracks/rust/exercises/grains/README.md +3 -2
  220. data/tracks/rust/exercises/hamming/README.md +3 -2
  221. data/tracks/rust/exercises/hello-world/GETTING_STARTED.md +1 -1
  222. data/tracks/rust/exercises/hello-world/README.md +3 -2
  223. data/tracks/rust/exercises/hexadecimal/README.md +3 -2
  224. data/tracks/rust/exercises/isogram/.gitignore +8 -0
  225. data/tracks/rust/exercises/isogram/Cargo.toml +3 -0
  226. data/tracks/rust/exercises/isogram/README.md +52 -0
  227. data/tracks/rust/exercises/isogram/example.rs +12 -0
  228. data/tracks/rust/exercises/isogram/src/lib.rs +0 -0
  229. data/tracks/rust/exercises/isogram/tests/isogram.rs +72 -0
  230. data/tracks/rust/exercises/largest-series-product/README.md +3 -2
  231. data/tracks/rust/exercises/leap/README.md +3 -2
  232. data/tracks/rust/exercises/leap/src/lib.rs +1 -1
  233. data/tracks/rust/exercises/luhn-from/README.md +3 -2
  234. data/tracks/rust/exercises/luhn-trait/.meta/description.md +2 -2
  235. data/tracks/rust/exercises/luhn-trait/README.md +5 -4
  236. data/tracks/rust/exercises/luhn/README.md +3 -2
  237. data/tracks/rust/exercises/minesweeper/README.md +3 -2
  238. data/tracks/rust/exercises/nth-prime/README.md +3 -2
  239. data/tracks/rust/exercises/nucleotide-codons/README.md +3 -2
  240. data/tracks/rust/exercises/nucleotide-count/README.md +3 -2
  241. data/tracks/rust/exercises/ocr-numbers/README.md +3 -2
  242. data/tracks/rust/exercises/pangram/README.md +3 -2
  243. data/tracks/rust/exercises/parallel-letter-frequency/HINTS.md +1 -1
  244. data/tracks/rust/exercises/parallel-letter-frequency/README.md +4 -3
  245. data/tracks/rust/exercises/pascals-triangle/README.md +3 -2
  246. data/tracks/rust/exercises/perfect-numbers/README.md +3 -2
  247. data/tracks/rust/exercises/phone-number/README.md +3 -2
  248. data/tracks/rust/exercises/pig-latin/README.md +3 -2
  249. data/tracks/rust/exercises/poker/README.md +3 -2
  250. data/tracks/rust/exercises/prime-factors/README.md +3 -2
  251. data/tracks/rust/exercises/protein-translation/README.md +3 -2
  252. data/tracks/rust/exercises/proverb/README.md +3 -2
  253. data/tracks/rust/exercises/proverb/src/lib.rs +1 -1
  254. data/tracks/rust/exercises/pythagorean-triplet/README.md +3 -2
  255. data/tracks/rust/exercises/queen-attack/README.md +3 -2
  256. data/tracks/rust/exercises/raindrops/README.md +3 -2
  257. data/tracks/rust/exercises/raindrops/src/lib.rs +1 -1
  258. data/tracks/rust/exercises/react/README.md +3 -2
  259. data/tracks/rust/exercises/rectangles/README.md +3 -2
  260. data/tracks/rust/exercises/rna-transcription/README.md +3 -2
  261. data/tracks/rust/exercises/robot-name/README.md +3 -2
  262. data/tracks/rust/exercises/robot-simulator/README.md +3 -2
  263. data/tracks/rust/exercises/roman-numerals/README.md +3 -2
  264. data/tracks/rust/exercises/rotational-cipher/README.md +3 -2
  265. data/tracks/rust/exercises/run-length-encoding/README.md +3 -2
  266. data/tracks/rust/exercises/say/README.md +3 -2
  267. data/tracks/rust/exercises/scrabble-score/README.md +3 -2
  268. data/tracks/rust/exercises/sieve/README.md +3 -2
  269. data/tracks/rust/exercises/space-age/README.md +3 -2
  270. data/tracks/rust/exercises/sublist/README.md +3 -2
  271. data/tracks/rust/exercises/sum-of-multiples/README.md +3 -2
  272. data/tracks/rust/exercises/sum-of-multiples/src/lib.rs +1 -1
  273. data/tracks/rust/exercises/tournament/README.md +3 -2
  274. data/tracks/rust/exercises/triangle/HINTS.md +2 -2
  275. data/tracks/rust/exercises/triangle/README.md +5 -4
  276. data/tracks/rust/exercises/variable-length-quantity/README.md +3 -2
  277. data/tracks/rust/exercises/word-count/README.md +3 -2
  278. data/tracks/rust/exercises/wordy/README.md +3 -2
  279. metadata +38 -3
  280. data/tracks/ecmascript/yarn.lock +0 -3144
@@ -1,2 +1,2 @@
1
- def nth_prime():
1
+ def nth_prime(positive_number):
2
2
  pass
@@ -18,6 +18,9 @@ each nucleotide with its complement:
18
18
  * `T` -> `A`
19
19
  * `A` -> `U`
20
20
 
21
+ Your function will need to be able to handle invalid inputs by raising a
22
+ `ValueError` with a meaningful message.
23
+
21
24
  ## Submitting Exercises
22
25
 
23
26
  Note that, when trying to submit an exercise, make sure the solution is in the `exercism/python/<exerciseName>` directory.
@@ -31,5 +34,7 @@ please see the [help page](http://exercism.io/languages/python).
31
34
 
32
35
  Rosalind [http://rosalind.info/problems/rna](http://rosalind.info/problems/rna)
33
36
 
37
+ Note that in this problem we are finding the complement, so we also swap for the complementary bases - unlike the Rosalind problem which is just swapping T for U.
38
+
34
39
  ## Submitting Incomplete Solutions
35
40
  It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -13,6 +13,6 @@ DNA_TO_RNA = maketrans(DNA_CHARS, 'UCGA')
13
13
  def to_rna(dna_strand):
14
14
  valid_chars = set(DNA_CHARS)
15
15
  if any(char not in valid_chars for char in dna_strand):
16
- return ''
16
+ raise ValueError("Input DNA strand contains invalid bases")
17
17
 
18
18
  return dna_strand.translate(DNA_TO_RNA)
@@ -20,16 +20,19 @@ class DNATests(unittest.TestCase):
20
20
  self.assertEqual(to_rna('A'), 'U')
21
21
 
22
22
  def test_transcribes_all_occurences(self):
23
- self.assertMultiLineEqual(to_rna('ACGTGGTCTTAA'), 'UGCACCAGAAUU')
23
+ self.assertEqual(to_rna('ACGTGGTCTTAA'), 'UGCACCAGAAUU')
24
24
 
25
25
  def test_correctly_handles_single_invalid_input(self):
26
- self.assertEqual(to_rna('U'), '')
26
+ with self.assertRaises(ValueError):
27
+ to_rna('U')
27
28
 
28
29
  def test_correctly_handles_completely_invalid_input(self):
29
- self.assertMultiLineEqual(to_rna('XXX'), '')
30
+ with self.assertRaises(ValueError):
31
+ to_rna('XXX')
30
32
 
31
33
  def test_correctly_handles_partially_invalid_input(self):
32
- self.assertMultiLineEqual(to_rna('ACGTXXXCTTAA'), '')
34
+ with self.assertRaises(ValueError):
35
+ to_rna('ACGTXXXCTTAA')
33
36
 
34
37
 
35
38
  if __name__ == '__main__':
@@ -3,6 +3,8 @@ import unittest
3
3
  from robot_simulator import Robot, NORTH, EAST, SOUTH, WEST
4
4
 
5
5
 
6
+ # Tests adapted from `problem-specifications//canonical-data.json` @ v2.0.0
7
+
6
8
  class RobotTests(unittest.TestCase):
7
9
  def test_init(self):
8
10
  robot = Robot()
@@ -32,19 +34,19 @@ class RobotTests(unittest.TestCase):
32
34
  self.assertEqual(robot.coordinates, (0, 1))
33
35
  self.assertEqual(robot.bearing, NORTH)
34
36
 
35
- def test_advance_positive_east(self):
36
- robot = Robot(EAST, 0, 0)
37
- robot.advance()
38
- self.assertEqual(robot.coordinates, (1, 0))
39
- self.assertEqual(robot.bearing, EAST)
40
-
41
37
  def test_advance_negative_south(self):
42
38
  robot = Robot(SOUTH, 0, 0)
43
39
  robot.advance()
44
40
  self.assertEqual(robot.coordinates, (0, -1))
45
41
  self.assertEqual(robot.bearing, SOUTH)
46
42
 
47
- def test_advance_positive_west(self):
43
+ def test_advance_positive_east(self):
44
+ robot = Robot(EAST, 0, 0)
45
+ robot.advance()
46
+ self.assertEqual(robot.coordinates, (1, 0))
47
+ self.assertEqual(robot.bearing, EAST)
48
+
49
+ def test_advance_negative_west(self):
48
50
  robot = Robot(WEST, 0, 0)
49
51
  robot.advance()
50
52
  self.assertEqual(robot.coordinates, (-1, 0))
@@ -10,21 +10,31 @@ import unittest
10
10
  from saddle_points import saddle_points
11
11
 
12
12
 
13
+ # Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0
14
+
13
15
  class SaddlePointTest(unittest.TestCase):
14
16
  def test_one_saddle(self):
15
17
  inp = [[9, 8, 7], [5, 3, 2], [6, 6, 7]]
16
18
  self.assertEqual(saddle_points(inp), set([(1, 0)]))
17
19
 
20
+ def test_empty_matrix(self):
21
+ self.assertEqual(saddle_points([]), set())
22
+
18
23
  def test_no_saddle(self):
19
- self.assertEqual(saddle_points([[2, 1], [1, 2]]), set())
24
+ inp = [[1, 2, 3], [3, 1, 2], [2, 3, 1]]
25
+ self.assertEqual(saddle_points(inp), set())
20
26
 
21
27
  def test_mult_saddle(self):
22
- inp = [[5, 3, 5, 4], [6, 4, 7, 3], [5, 1, 5, 3]]
23
- ans = set([(0, 0), (0, 2), (2, 0), (2, 2)])
28
+ inp = [[4, 5, 4], [3, 5, 5], [1, 5, 4]]
29
+ ans = set([(0, 1), (1, 1), (2, 1)])
24
30
  self.assertEqual(saddle_points(inp), ans)
25
31
 
26
- def test_empty_matrix(self):
27
- self.assertEqual(saddle_points([]), set())
32
+ def test_indentify_saddle_bottom_right_corner(self):
33
+ inp = [[8, 7, 9], [6, 7, 6], [3, 2, 5]]
34
+ ans = set([(2, 2)])
35
+ self.assertEqual(saddle_points(inp), ans)
36
+
37
+ # Additional tests for this track
28
38
 
29
39
  def test_irregular_matrix(self):
30
40
  inp = [[3, 2, 1], [0, 1], [2, 1, 0]]
@@ -1,5 +1,11 @@
1
1
  class Cipher(object):
2
- def __init__(self):
2
+ def __init__(self, key=None):
3
+ pass
4
+
5
+ def encode(self, text):
6
+ pass
7
+
8
+ def decode(self, text):
3
9
  pass
4
10
 
5
11
 
@@ -1,8 +1,10 @@
1
+ import re
2
+
1
3
  from collections import Counter
2
4
 
3
5
 
6
+ WORDS = re.compile("[a-z0-9]+(['][a-z]+)?")
7
+
8
+
4
9
  def word_count(text):
5
- def replace_nonalpha(char):
6
- return char.lower() if char.isalnum() else ' '
7
- text = ''.join(replace_nonalpha(c) for c in text)
8
- return Counter(text.split())
10
+ return Counter(word.group(0) for word in WORDS.finditer(text.lower()))
@@ -7,66 +7,93 @@ class WordCountTests(unittest.TestCase):
7
7
 
8
8
  def test_count_one_word(self):
9
9
  self.assertEqual(
10
- {'word': 1},
11
- word_count('word')
10
+ word_count('word'),
11
+ {'word': 1}
12
12
  )
13
13
 
14
14
  def test_count_one_of_each(self):
15
15
  self.assertEqual(
16
- {'one': 1, 'of': 1, 'each': 1},
17
- word_count('one of each')
16
+ word_count('one of each'),
17
+ {'one': 1, 'of': 1, 'each': 1}
18
18
  )
19
19
 
20
20
  def test_count_multiple_occurences(self):
21
21
  self.assertEqual(
22
- {'one': 1, 'fish': 4, 'two': 1, 'red': 1, 'blue': 1},
23
- word_count('one fish two fish red fish blue fish')
22
+ word_count('one fish two fish red fish blue fish'),
23
+ {'one': 1, 'fish': 4, 'two': 1, 'red': 1, 'blue': 1}
24
+ )
25
+
26
+ def test_cramped_list(self):
27
+ self.assertEqual(
28
+ word_count('one,two,three'),
29
+ {'one': 1, 'two': 1, 'three': 1}
30
+ )
31
+
32
+ def test_expanded_list(self):
33
+ self.assertEqual(
34
+ word_count('one,\ntwo,\nthree'),
35
+ {'one': 1, 'two': 1, 'three': 1}
24
36
  )
25
37
 
26
38
  def test_ignores_punctuation(self):
27
39
  self.assertEqual(
28
- {'car': 1, 'carpet': 1, 'as': 1, 'java': 1, 'javascript': 1},
29
- word_count('car : carpet as java : javascript!!&@$%^&')
40
+ word_count('car : carpet as java : javascript!!&@$%^&'),
41
+ {'car': 1, 'carpet': 1, 'as': 1, 'java': 1, 'javascript': 1}
30
42
  )
31
43
 
32
44
  def test_include_numbers(self):
33
45
  self.assertEqual(
34
- {'testing': 2, '1': 1, '2': 1},
35
- word_count('testing 1 2 testing')
46
+ word_count('testing 1 2 testing'),
47
+ {'testing': 2, '1': 1, '2': 1}
36
48
  )
37
49
 
38
50
  def test_mixed_case(self):
39
51
  self.assertEqual(
40
- [2, 3],
41
- sorted(list(word_count('go Go GO Stop stop').values()))
52
+ word_count('go Go GO Stop stop'),
53
+ {'go': 3, 'stop': 2}
54
+ )
55
+
56
+ def test_apostrophes(self):
57
+ self.assertEqual(
58
+ word_count("First: don't laugh. Then: don't cry."),
59
+ {'first': 1, "don't": 2, 'laugh': 1, 'then': 1, 'cry': 1}
42
60
  )
43
61
 
62
+ def test_quotations(self):
63
+ self.assertEqual(
64
+ word_count("Joe can't tell between 'large' and large."),
65
+ {'joe': 1, "can't": 1, 'tell': 1, 'between': 1, 'large': 2,
66
+ 'and': 1}
67
+ )
68
+
69
+ # Additional tests for this track
70
+
44
71
  def test_multiple_spaces(self):
45
72
  self.assertEqual(
46
- {'wait': 1, 'for': 1, 'it': 1},
47
- word_count('wait for it')
73
+ word_count('wait for it'),
74
+ {'wait': 1, 'for': 1, 'it': 1}
48
75
  )
49
76
 
50
77
  def test_newlines(self):
51
78
  self.assertEqual(
52
- {'rah': 2, 'ah': 3, 'roma': 2, 'ma': 1, 'ga': 2, 'oh': 1, 'la': 2,
53
- 'want': 1, 'your': 1, 'bad': 1, 'romance': 1},
54
79
  word_count('rah rah ah ah ah\nroma roma ma\n'
55
- 'ga ga oh la la\nwant your bad romance')
80
+ 'ga ga oh la la\nwant your bad romance'),
81
+ {'rah': 2, 'ah': 3, 'roma': 2, 'ma': 1, 'ga': 2, 'oh': 1, 'la': 2,
82
+ 'want': 1, 'your': 1, 'bad': 1, 'romance': 1}
56
83
  )
57
84
 
58
85
  def test_tabs(self):
59
86
  self.assertEqual(
60
- {'rah': 2, 'ah': 3, 'roma': 2, 'ma': 1, 'ga': 2, 'oh': 1, 'la': 2,
61
- 'want': 1, 'your': 1, 'bad': 1, 'romance': 1},
62
87
  word_count('rah rah ah ah ah\troma roma ma\tga ga oh la la\t'
63
- 'want your bad romance')
88
+ 'want your bad romance'),
89
+ {'rah': 2, 'ah': 3, 'roma': 2, 'ma': 1, 'ga': 2, 'oh': 1, 'la': 2,
90
+ 'want': 1, 'your': 1, 'bad': 1, 'romance': 1}
64
91
  )
65
92
 
66
93
  def test_non_alphanumeric(self):
67
94
  self.assertEqual(
68
- {'hey': 1, 'my': 1, 'spacebar': 1, 'is': 1, 'broken': 1},
69
- word_count('hey,my_spacebar_is_broken.')
95
+ word_count('hey,my_spacebar_is_broken.'),
96
+ {'hey': 1, 'my': 1, 'spacebar': 1, 'is': 1, 'broken': 1}
70
97
  )
71
98
 
72
99
 
@@ -3,8 +3,111 @@ import unittest
3
3
  from word_search import WordSearch, Point
4
4
 
5
5
 
6
+ # Tests adapted from `problem-specifications//canonical-data.json` @ v1.1.0
7
+
6
8
  class WordSearchTests(unittest.TestCase):
7
9
 
10
+ def test_initial_game_grid(self):
11
+ puzzle = 'jefblpepre'
12
+ searchAnswer = WordSearch(puzzle).search('clojure')
13
+ self.assertIsNone(searchAnswer)
14
+
15
+ def test_left_to_right_word(self):
16
+ puzzle = 'clojurermt'
17
+ searchAnswer = WordSearch(puzzle).search('clojure')
18
+ self.assertEqual(searchAnswer, (Point(0, 0), Point(6, 0)))
19
+
20
+ def test_left_to_right_word_different_position(self):
21
+ puzzle = 'mtclojurer'
22
+ searchAnswer = WordSearch(puzzle).search('clojure')
23
+ self.assertEqual(searchAnswer, (Point(2, 0), Point(8, 0)))
24
+
25
+ def test_different_left_to_right_word(self):
26
+ puzzle = 'coffeelplx'
27
+ searchAnswer = WordSearch(puzzle).search('coffee')
28
+ self.assertEqual(searchAnswer, (Point(0, 0), Point(5, 0)))
29
+
30
+ def test_different_left_to_right_word_different_position(self):
31
+ puzzle = 'xcoffeezlp'
32
+ searchAnswer = WordSearch(puzzle).search('coffee')
33
+ self.assertEqual(searchAnswer, (Point(1, 0), Point(6, 0)))
34
+
35
+ def test_left_to_right_word_two_lines(self):
36
+ puzzle = ('jefblpepre\n'
37
+ 'tclojurerm\n')
38
+ searchAnswer = WordSearch(puzzle).search('clojure')
39
+ self.assertEqual(searchAnswer, (Point(1, 1), Point(7, 1)))
40
+
41
+ def test_left_to_right_word_three_lines(self):
42
+ puzzle = ('camdcimgtc\n'
43
+ 'jefblpepre\n'
44
+ 'clojurermt\n')
45
+ searchAnswer = WordSearch(puzzle).search('clojure')
46
+ self.assertEqual(searchAnswer, (Point(0, 2), Point(6, 2)))
47
+
48
+ def test_left_to_right_word_ten_lines(self):
49
+ puzzle = ('jefblpepre\n'
50
+ 'camdcimgtc\n'
51
+ 'oivokprjsm\n'
52
+ 'pbwasqroua\n'
53
+ 'rixilelhrs\n'
54
+ 'wolcqlirpc\n'
55
+ 'screeaumgr\n'
56
+ 'alxhpburyi\n'
57
+ 'jalaycalmp\n'
58
+ 'clojurermt\n')
59
+ searchAnswer = WordSearch(puzzle).search('clojure')
60
+ self.assertEqual(searchAnswer, (Point(0, 9), Point(6, 9)))
61
+
62
+ def test_left_to_right_word_ten_lines_different_position(self):
63
+ puzzle = ('jefblpepre\n'
64
+ 'camdcimgtc\n'
65
+ 'oivokprjsm\n'
66
+ 'pbwasqroua\n'
67
+ 'rixilelhrs\n'
68
+ 'wolcqlirpc\n'
69
+ 'screeaumgr\n'
70
+ 'alxhpburyi\n'
71
+ 'clojurermt\n'
72
+ 'jalaycalmp\n')
73
+ searchAnswer = WordSearch(puzzle).search('clojure')
74
+ self.assertEqual(searchAnswer, (Point(0, 8), Point(6, 8)))
75
+
76
+ def test_different_left_to_right_word_ten_lines(self):
77
+ puzzle = ('jefblpepre\n'
78
+ 'camdcimgtc\n'
79
+ 'oivokprjsm\n'
80
+ 'pbwasqroua\n'
81
+ 'rixilelhrs\n'
82
+ 'wolcqlirpc\n'
83
+ 'fortranftw\n'
84
+ 'alxhpburyi\n'
85
+ 'clojurermt\n'
86
+ 'jalaycalmp\n')
87
+ searchAnswer = WordSearch(puzzle).search('fortran')
88
+ self.assertEqual(searchAnswer, (Point(0, 6), Point(6, 6)))
89
+
90
+ def test_multiple_words(self):
91
+ puzzle = ('jefblpepre\n'
92
+ 'camdcimgtc\n'
93
+ 'oivokprjsm\n'
94
+ 'pbwasqroua\n'
95
+ 'rixilelhrs\n'
96
+ 'wolcqlirpc\n'
97
+ 'fortranftw\n'
98
+ 'alxhpburyi\n'
99
+ 'jalaycalmp\n'
100
+ 'clojurermt\n')
101
+ searchAnswer = WordSearch(puzzle).search('fortran')
102
+ self.assertEqual(searchAnswer, (Point(0, 6), Point(6, 6)))
103
+ searchAnswer = WordSearch(puzzle).search('clojure')
104
+ self.assertEqual(searchAnswer, (Point(0, 9), Point(6, 9)))
105
+
106
+ def test_single_word_right_to_left(self):
107
+ puzzle = 'rixilelhrs'
108
+ searchAnswer = WordSearch(puzzle).search('elixir')
109
+ self.assertEqual(searchAnswer, (Point(5, 0), Point(0, 0)))
110
+
8
111
  @classmethod
9
112
  def setUpClass(self):
10
113
  puzzle = ('jefblpepre\n'
@@ -19,13 +122,11 @@ class WordSearchTests(unittest.TestCase):
19
122
  'clojurermt')
20
123
  self.example = WordSearch(puzzle)
21
124
 
22
- def test_horizontal_words_left_to_right(self):
125
+ def test_horizontal_words_different_directions(self):
23
126
  self.assertEqual(
24
127
  self.example.search('clojure'),
25
128
  (Point(0, 9), Point(6, 9))
26
129
  )
27
-
28
- def test_horizontal_words_right_to_left(self):
29
130
  self.assertEqual(
30
131
  self.example.search('elixir'),
31
132
  (Point(5, 4), Point(0, 4))
@@ -70,15 +171,6 @@ class WordSearchTests(unittest.TestCase):
70
171
  def test_words_that_are_not_in_the_puzzle(self):
71
172
  self.assertIsNone(self.example.search('haskell'))
72
173
 
73
- def test_search_differently_sized_puzzles(self):
74
- puzzle = ('qwertyuiopz\n'
75
- 'luamsicrexe\n'
76
- 'abcdefghijk')
77
- self.assertEqual(
78
- WordSearch(puzzle).search('exercism'),
79
- (Point(10, 1), Point(3, 1))
80
- )
81
-
82
174
 
83
175
  if __name__ == '__main__':
84
176
  unittest.main()
@@ -2,6 +2,8 @@
2
2
  language: rust
3
3
  script:
4
4
  - "./_test/check-exercises.sh"
5
+ - "sh ./_test/ensure-lib-src-rs-exist.sh"
6
+ - "sh ./_test/ensure-stubs-compile.sh"
5
7
  - "sh ./_test/count-ignores.sh"
6
8
  - "./bin/fetch-configlet"
7
9
  - "./bin/configlet lint ."
@@ -82,6 +82,11 @@ Note that:
82
82
 
83
83
  - The stub file and test suite should use only the Rust core libraries. `Cargo.toml` should not list any external dependencies as we don't want to make the student assume required crates. If an `example.rs` uses external crates, include `Cargo-example.toml` so that `_tests/check-exercises.sh` can compile with these when testing.
84
84
 
85
+ - Except in extraordinary circumstances, the stub file should compile under `cargo test --no-run`.
86
+ This allows us to check that the signatures in the stub file match the signatures expected by the tests.
87
+ Use `unimplemented!()` as the body of each function to achieve this.
88
+ If there is a justified reason why this is not possible, instead include a `.meta/ALLOWED_TO_NOT_COMPILE` containing the reason.
89
+
85
90
  - If porting an existing exercise from problem-specifications that has a `canonical-data.json` file, use the version in `canonical-data.json` for that exercise as your `Cargo.toml` version. Otherwise, use "0.0.0".
86
91
 
87
92
  - An exercise may contain `.meta/hints.md`. This is optional and will appear after the normal exercise
@@ -32,12 +32,6 @@ for exercise in $files; do
32
32
  (
33
33
  cd $workdir
34
34
 
35
- if [ ! -f src/lib.rs ]; then
36
- # https://github.com/exercism/rust/pull/270
37
- echo "$exercise is missing a src/lib.rs; please create one (an empty file is acceptable)"
38
- exitcode=1
39
- fi
40
-
41
35
  cp example.rs src/lib.rs
42
36
 
43
37
  # Overwrite empty Cargo.toml if an example specific file exists