trackler 2.2.1.44 → 2.2.1.45

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 (452) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/isbn-verifier/canonical-data.json +88 -0
  4. data/problem-specifications/exercises/isbn-verifier/description.md +35 -0
  5. data/problem-specifications/exercises/isbn-verifier/metadata.yml +4 -0
  6. data/problem-specifications/exercises/robot-simulator/canonical-data.json +125 -32
  7. data/problem-specifications/exercises/sum-of-multiples/description.md +0 -3
  8. data/problem-specifications/exercises/two-bucket/canonical-data.json +3 -3
  9. data/tracks/c/config.json +235 -237
  10. data/tracks/c/exercises/acronym/README.md +0 -1
  11. data/tracks/c/exercises/all-your-base/README.md +1 -1
  12. data/tracks/c/exercises/allergies/README.md +0 -1
  13. data/tracks/c/exercises/atbash-cipher/README.md +2 -1
  14. data/tracks/c/exercises/beer-song/README.md +1 -1
  15. data/tracks/c/exercises/binary/README.md +2 -0
  16. data/tracks/c/exercises/grains/README.md +0 -1
  17. data/tracks/c/exercises/isogram/README.md +2 -1
  18. data/tracks/c/exercises/leap/README.md +1 -1
  19. data/tracks/c/exercises/meetup/README.md +1 -2
  20. data/tracks/c/exercises/nucleotide-count/README.md +8 -22
  21. data/tracks/c/exercises/palindrome-products/README.md +12 -6
  22. data/tracks/c/exercises/pangram/README.md +1 -1
  23. data/tracks/c/exercises/pascals-triangle/README.md +1 -1
  24. data/tracks/c/exercises/perfect-numbers/README.md +2 -2
  25. data/tracks/c/exercises/phone-number/README.md +3 -2
  26. data/tracks/c/exercises/roman-numerals/README.md +1 -1
  27. data/tracks/c/exercises/scrabble-score/README.md +3 -1
  28. data/tracks/c/exercises/space-age/README.md +2 -1
  29. data/tracks/c/exercises/triangle/README.md +9 -6
  30. data/tracks/c/exercises/word-count/README.md +1 -2
  31. data/tracks/csharp/exercises/accumulate/Accumulate.csproj +2 -2
  32. data/tracks/csharp/exercises/acronym/Acronym.csproj +2 -2
  33. data/tracks/csharp/exercises/all-your-base/AllYourBase.csproj +2 -2
  34. data/tracks/csharp/exercises/allergies/Allergies.csproj +2 -2
  35. data/tracks/csharp/exercises/alphametics/Alphametics.csproj +2 -2
  36. data/tracks/csharp/exercises/anagram/Anagram.csproj +2 -2
  37. data/tracks/csharp/exercises/atbash-cipher/AtbashCipher.csproj +2 -2
  38. data/tracks/csharp/exercises/bank-account/BankAccount.csproj +2 -2
  39. data/tracks/csharp/exercises/beer-song/BeerSong.csproj +2 -2
  40. data/tracks/csharp/exercises/binary-search/BinarySearch.csproj +2 -2
  41. data/tracks/csharp/exercises/binary-search-tree/BinarySearchTree.csproj +2 -2
  42. data/tracks/csharp/exercises/bob/Bob.csproj +2 -2
  43. data/tracks/csharp/exercises/book-store/BookStore.csproj +2 -2
  44. data/tracks/csharp/exercises/bowling/Bowling.csproj +2 -2
  45. data/tracks/csharp/exercises/bracket-push/BracketPush.csproj +2 -2
  46. data/tracks/csharp/exercises/change/Change.csproj +2 -2
  47. data/tracks/csharp/exercises/circular-buffer/CircularBuffer.csproj +2 -2
  48. data/tracks/csharp/exercises/clock/Clock.csproj +2 -2
  49. data/tracks/csharp/exercises/collatz-conjecture/CollatzConjecture.csproj +2 -2
  50. data/tracks/csharp/exercises/complex-numbers/ComplexNumbers.csproj +2 -2
  51. data/tracks/csharp/exercises/connect/Connect.cs +1 -1
  52. data/tracks/csharp/exercises/connect/Connect.csproj +2 -2
  53. data/tracks/csharp/exercises/connect/ConnectTest.cs +120 -85
  54. data/tracks/csharp/exercises/connect/Example.cs +11 -7
  55. data/tracks/csharp/exercises/crypto-square/CryptoSquare.csproj +2 -2
  56. data/tracks/csharp/exercises/custom-set/CustomSet.csproj +2 -2
  57. data/tracks/csharp/exercises/diamond/Diamond.csproj +2 -2
  58. data/tracks/csharp/exercises/difference-of-squares/DifferenceOfSquares.csproj +2 -2
  59. data/tracks/csharp/exercises/diffie-hellman/DiffieHellman.csproj +2 -2
  60. data/tracks/csharp/exercises/dominoes/Dominoes.csproj +2 -2
  61. data/tracks/csharp/exercises/dot-dsl/DotDsl.csproj +2 -2
  62. data/tracks/csharp/exercises/error-handling/ErrorHandling.csproj +2 -2
  63. data/tracks/csharp/exercises/etl/Etl.csproj +2 -2
  64. data/tracks/csharp/exercises/flatten-array/FlattenArray.csproj +2 -2
  65. data/tracks/csharp/exercises/food-chain/FoodChain.csproj +2 -2
  66. data/tracks/csharp/exercises/forth/Forth.csproj +2 -2
  67. data/tracks/csharp/exercises/gigasecond/Gigasecond.csproj +2 -2
  68. data/tracks/csharp/exercises/go-counting/GoCounting.csproj +2 -2
  69. data/tracks/csharp/exercises/grade-school/GradeSchool.csproj +2 -2
  70. data/tracks/csharp/exercises/grains/Grains.csproj +2 -2
  71. data/tracks/csharp/exercises/grep/Grep.csproj +2 -2
  72. data/tracks/csharp/exercises/hamming/Hamming.csproj +2 -2
  73. data/tracks/csharp/exercises/hangman/Hangman.csproj +2 -2
  74. data/tracks/csharp/exercises/hello-world/HelloWorld.csproj +2 -2
  75. data/tracks/csharp/exercises/house/House.csproj +2 -2
  76. data/tracks/csharp/exercises/isogram/Isogram.csproj +2 -2
  77. data/tracks/csharp/exercises/kindergarten-garden/KindergartenGarden.csproj +2 -2
  78. data/tracks/csharp/exercises/largest-series-product/LargestSeriesProduct.csproj +2 -2
  79. data/tracks/csharp/exercises/leap/Leap.csproj +2 -2
  80. data/tracks/csharp/exercises/ledger/Ledger.csproj +2 -2
  81. data/tracks/csharp/exercises/linked-list/LinkedList.csproj +2 -2
  82. data/tracks/csharp/exercises/list-ops/ListOps.csproj +2 -2
  83. data/tracks/csharp/exercises/luhn/Luhn.csproj +2 -2
  84. data/tracks/csharp/exercises/markdown/Markdown.csproj +2 -2
  85. data/tracks/csharp/exercises/matrix/Matrix.csproj +2 -2
  86. data/tracks/csharp/exercises/meetup/Meetup.csproj +2 -2
  87. data/tracks/csharp/exercises/minesweeper/Minesweeper.csproj +2 -2
  88. data/tracks/csharp/exercises/nth-prime/NthPrime.csproj +2 -2
  89. data/tracks/csharp/exercises/nucleotide-count/NucleotideCount.csproj +2 -2
  90. data/tracks/csharp/exercises/ocr-numbers/OcrNumbers.csproj +2 -2
  91. data/tracks/csharp/exercises/palindrome-products/PalindromeProducts.csproj +2 -2
  92. data/tracks/csharp/exercises/pangram/Pangram.csproj +2 -2
  93. data/tracks/csharp/exercises/parallel-letter-frequency/ParallelLetterFrequency.csproj +2 -2
  94. data/tracks/csharp/exercises/pascals-triangle/PascalsTriangle.csproj +2 -2
  95. data/tracks/csharp/exercises/perfect-numbers/PerfectNumbers.csproj +2 -2
  96. data/tracks/csharp/exercises/phone-number/PhoneNumber.csproj +2 -2
  97. data/tracks/csharp/exercises/pig-latin/PigLatin.csproj +2 -2
  98. data/tracks/csharp/exercises/poker/Poker.csproj +2 -2
  99. data/tracks/csharp/exercises/pov/Pov.csproj +2 -2
  100. data/tracks/csharp/exercises/prime-factors/PrimeFactors.csproj +2 -2
  101. data/tracks/csharp/exercises/protein-translation/ProteinTranslation.csproj +2 -2
  102. data/tracks/csharp/exercises/proverb/Proverb.csproj +2 -2
  103. data/tracks/csharp/exercises/pythagorean-triplet/PythagoreanTriplet.csproj +2 -2
  104. data/tracks/csharp/exercises/queen-attack/QueenAttack.csproj +2 -2
  105. data/tracks/csharp/exercises/rail-fence-cipher/RailFenceCipher.csproj +2 -2
  106. data/tracks/csharp/exercises/raindrops/Raindrops.csproj +2 -2
  107. data/tracks/csharp/exercises/react/React.csproj +2 -2
  108. data/tracks/csharp/exercises/rectangles/Rectangles.csproj +2 -2
  109. data/tracks/csharp/exercises/rna-transcription/RnaTranscription.csproj +2 -2
  110. data/tracks/csharp/exercises/robot-name/RobotName.csproj +2 -2
  111. data/tracks/csharp/exercises/robot-simulator/RobotSimulator.csproj +2 -2
  112. data/tracks/csharp/exercises/roman-numerals/RomanNumerals.csproj +2 -2
  113. data/tracks/csharp/exercises/rotational-cipher/RotationalCipher.csproj +2 -2
  114. data/tracks/csharp/exercises/run-length-encoding/RunLengthEncoding.csproj +2 -2
  115. data/tracks/csharp/exercises/saddle-points/SaddlePoints.csproj +2 -2
  116. data/tracks/csharp/exercises/say/Say.csproj +2 -2
  117. data/tracks/csharp/exercises/scale-generator/ScaleGenerator.csproj +2 -2
  118. data/tracks/csharp/exercises/scrabble-score/ScrabbleScore.csproj +2 -2
  119. data/tracks/csharp/exercises/secret-handshake/SecretHandshake.csproj +2 -2
  120. data/tracks/csharp/exercises/series/Series.csproj +2 -2
  121. data/tracks/csharp/exercises/series/SeriesTest.cs +17 -17
  122. data/tracks/csharp/exercises/sgf-parsing/SgfParsing.csproj +2 -2
  123. data/tracks/csharp/exercises/sieve/Sieve.csproj +2 -2
  124. data/tracks/csharp/exercises/simple-cipher/SimpleCipher.csproj +2 -2
  125. data/tracks/csharp/exercises/simple-linked-list/SimpleLinkedList.csproj +2 -2
  126. data/tracks/csharp/exercises/space-age/SpaceAge.csproj +2 -2
  127. data/tracks/csharp/exercises/spiral-matrix/SpiralMatrix.csproj +2 -2
  128. data/tracks/csharp/exercises/strain/Strain.csproj +2 -2
  129. data/tracks/csharp/exercises/sublist/Sublist.csproj +2 -2
  130. data/tracks/csharp/exercises/sum-of-multiples/SumOfMultiples.csproj +2 -2
  131. data/tracks/csharp/exercises/tournament/Tournament.csproj +2 -2
  132. data/tracks/csharp/exercises/transpose/Transpose.csproj +2 -2
  133. data/tracks/csharp/exercises/tree-building/TreeBuilding.csproj +2 -2
  134. data/tracks/csharp/exercises/triangle/Triangle.cs +0 -11
  135. data/tracks/csharp/exercises/triangle/Triangle.csproj +2 -2
  136. data/tracks/csharp/exercises/triangle/TriangleTest.cs +17 -17
  137. data/tracks/csharp/exercises/twelve-days/TwelveDays.csproj +2 -2
  138. data/tracks/csharp/exercises/two-bucket/TwoBucket.csproj +2 -2
  139. data/tracks/csharp/exercises/two-fer/TwoFer.csproj +2 -2
  140. data/tracks/csharp/exercises/variable-length-quantity/VariableLengthQuantity.csproj +2 -2
  141. data/tracks/csharp/exercises/word-count/WordCount.csproj +2 -2
  142. data/tracks/csharp/exercises/word-search/WordSearch.csproj +2 -2
  143. data/tracks/csharp/exercises/wordy/Wordy.csproj +2 -2
  144. data/tracks/csharp/exercises/zebra-puzzle/ZebraPuzzle.csproj +2 -2
  145. data/tracks/csharp/exercises/zipper/Zipper.csproj +2 -2
  146. data/tracks/csharp/generators/Exercises/Connect.cs +47 -0
  147. data/tracks/csharp/generators/Exercises/Triangle.cs +1 -1
  148. data/tracks/dart/config/maintainers.json +27 -1
  149. data/tracks/dart/pubspec.yaml +3 -0
  150. data/tracks/dart/tool/create-exercise +144 -5
  151. data/tracks/elm/.gitattributes +1 -0
  152. data/tracks/elm/bin/install-elm-format +9 -3
  153. data/tracks/elm/config.json +30 -0
  154. data/tracks/elm/exercises/all-your-base/AllYourBase.elm +1 -0
  155. data/tracks/elm/exercises/all-your-base/AllYourBase.example.elm +68 -0
  156. data/tracks/elm/exercises/all-your-base/README.md +65 -0
  157. data/tracks/elm/exercises/all-your-base/elm-package.json +15 -0
  158. data/tracks/elm/exercises/all-your-base/tests/Tests.elm +53 -0
  159. data/tracks/elm/exercises/all-your-base/tests/elm-package.json +16 -0
  160. data/tracks/elm/exercises/collatz-conjecture/CollatzConjecture.elm +2 -0
  161. data/tracks/elm/exercises/collatz-conjecture/CollatzConjecture.example.elm +19 -0
  162. data/tracks/elm/exercises/collatz-conjecture/elm-package.json +15 -0
  163. data/tracks/elm/exercises/collatz-conjecture/package.json +14 -0
  164. data/tracks/elm/exercises/collatz-conjecture/tests/Tests.elm +38 -0
  165. data/tracks/elm/exercises/collatz-conjecture/tests/elm-package.json +16 -0
  166. data/tracks/elm/exercises/isogram/Isogram.elm +1 -0
  167. data/tracks/elm/exercises/isogram/Isogram.example.elm +76 -0
  168. data/tracks/elm/exercises/isogram/README.md +50 -0
  169. data/tracks/elm/exercises/isogram/elm-package.json +14 -0
  170. data/tracks/elm/exercises/isogram/package.json +14 -0
  171. data/tracks/elm/exercises/isogram/tests/Tests.elm +46 -0
  172. data/tracks/elm/exercises/isogram/tests/elm-package.json +16 -0
  173. data/tracks/fsharp/.gitignore +2 -1
  174. data/tracks/fsharp/exercises/accumulate/Accumulate.fsproj +3 -2
  175. data/tracks/fsharp/exercises/acronym/Acronym.fs +1 -1
  176. data/tracks/fsharp/exercises/acronym/Acronym.fsproj +3 -2
  177. data/tracks/fsharp/exercises/acronym/AcronymTest.fs +13 -38
  178. data/tracks/fsharp/exercises/acronym/Example.fs +1 -1
  179. data/tracks/fsharp/exercises/all-your-base/AllYourBase.fsproj +3 -2
  180. data/tracks/fsharp/exercises/all-your-base/AllYourBaseTest.fs +64 -61
  181. data/tracks/fsharp/exercises/all-your-base/Example.fs +4 -1
  182. data/tracks/fsharp/exercises/allergies/Allergies.fs +2 -2
  183. data/tracks/fsharp/exercises/allergies/Allergies.fsproj +3 -2
  184. data/tracks/fsharp/exercises/allergies/AllergiesTest.fs +28 -37
  185. data/tracks/fsharp/exercises/allergies/Example.fs +3 -3
  186. data/tracks/fsharp/exercises/alphametics/Alphametics.fsproj +3 -2
  187. data/tracks/fsharp/exercises/anagram/Anagram.fsproj +3 -2
  188. data/tracks/fsharp/exercises/atbash-cipher/AtbashCipher.fs +4 -2
  189. data/tracks/fsharp/exercises/atbash-cipher/AtbashCipher.fsproj +3 -2
  190. data/tracks/fsharp/exercises/atbash-cipher/AtbashCipherTest.fs +38 -42
  191. data/tracks/fsharp/exercises/atbash-cipher/Example.fs +5 -3
  192. data/tracks/fsharp/exercises/bank-account/BankAccount.fsproj +3 -2
  193. data/tracks/fsharp/exercises/beer-song/BeerSong.fsproj +3 -2
  194. data/tracks/fsharp/exercises/beer-song/BeerSongTest.fs +36 -32
  195. data/tracks/fsharp/exercises/beer-song/Example.fs +2 -2
  196. data/tracks/fsharp/exercises/binary-search/BinarySearch.fsproj +3 -2
  197. data/tracks/fsharp/exercises/binary-search-tree/BinarySearchTree.fsproj +3 -2
  198. data/tracks/fsharp/exercises/bob/Bob.fs +1 -1
  199. data/tracks/fsharp/exercises/bob/Bob.fsproj +3 -2
  200. data/tracks/fsharp/exercises/bob/BobTest.fs +64 -20
  201. data/tracks/fsharp/exercises/bob/Example.fs +3 -4
  202. data/tracks/fsharp/exercises/book-store/BookStore.fs +1 -1
  203. data/tracks/fsharp/exercises/book-store/BookStore.fsproj +3 -2
  204. data/tracks/fsharp/exercises/book-store/BookStoreTest.fs +32 -25
  205. data/tracks/fsharp/exercises/book-store/Example.fs +1 -1
  206. data/tracks/fsharp/exercises/bowling/Bowling.fsproj +3 -2
  207. data/tracks/fsharp/exercises/bracket-push/BracketPush.fs +1 -1
  208. data/tracks/fsharp/exercises/bracket-push/BracketPush.fsproj +3 -2
  209. data/tracks/fsharp/exercises/bracket-push/BracketPushTest.fs +24 -25
  210. data/tracks/fsharp/exercises/bracket-push/Example.fs +1 -1
  211. data/tracks/fsharp/exercises/change/Change.fs +1 -1
  212. data/tracks/fsharp/exercises/change/Change.fsproj +3 -2
  213. data/tracks/fsharp/exercises/change/ChangeTest.fs +42 -18
  214. data/tracks/fsharp/exercises/change/Example.fs +7 -4
  215. data/tracks/fsharp/exercises/circular-buffer/CircularBuffer.fsproj +3 -2
  216. data/tracks/fsharp/exercises/clock/Clock.fsproj +3 -2
  217. data/tracks/fsharp/exercises/connect/Connect.fsproj +3 -2
  218. data/tracks/fsharp/exercises/crypto-square/CryptoSquare.fs +1 -40
  219. data/tracks/fsharp/exercises/crypto-square/CryptoSquare.fsproj +3 -2
  220. data/tracks/fsharp/exercises/crypto-square/CryptoSquareTest.fs +16 -40
  221. data/tracks/fsharp/exercises/crypto-square/Example.fs +13 -16
  222. data/tracks/fsharp/exercises/custom-set/CustomSet.fs +12 -12
  223. data/tracks/fsharp/exercises/custom-set/CustomSet.fsproj +3 -2
  224. data/tracks/fsharp/exercises/diamond/Diamond.fsproj +3 -2
  225. data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquares.fs +2 -2
  226. data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquares.fsproj +3 -2
  227. data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquaresTest.fs +24 -20
  228. data/tracks/fsharp/exercises/difference-of-squares/Example.fs +3 -3
  229. data/tracks/fsharp/exercises/diffie-hellman/DiffieHellman.fsproj +3 -2
  230. data/tracks/fsharp/exercises/dominoes/Dominoes.fsproj +3 -2
  231. data/tracks/fsharp/exercises/dot-dsl/DotDsl.fsproj +3 -2
  232. data/tracks/fsharp/exercises/error-handling/ErrorHandling.fsproj +3 -2
  233. data/tracks/fsharp/exercises/etl/Etl.fsproj +3 -2
  234. data/tracks/fsharp/exercises/food-chain/FoodChain.fsproj +3 -2
  235. data/tracks/fsharp/exercises/forth/Forth.fsproj +3 -2
  236. data/tracks/fsharp/exercises/gigasecond/Example.fs +1 -3
  237. data/tracks/fsharp/exercises/gigasecond/Gigasecond.fs +1 -1
  238. data/tracks/fsharp/exercises/gigasecond/Gigasecond.fsproj +3 -2
  239. data/tracks/fsharp/exercises/gigasecond/GigasecondTest.fs +21 -12
  240. data/tracks/fsharp/exercises/go-counting/GoCounting.fsproj +3 -2
  241. data/tracks/fsharp/exercises/grade-school/GradeSchool.fsproj +3 -2
  242. data/tracks/fsharp/exercises/grains/Grains.fsproj +3 -2
  243. data/tracks/fsharp/exercises/grep/Grep.fsproj +3 -2
  244. data/tracks/fsharp/exercises/hamming/Hamming.fsproj +3 -2
  245. data/tracks/fsharp/exercises/hangman/Hangman.fsproj +3 -2
  246. data/tracks/fsharp/exercises/hello-world/HelloWorld.fsproj +3 -2
  247. data/tracks/fsharp/exercises/hello-world/HelloWorldTest.fs +6 -3
  248. data/tracks/fsharp/exercises/house/House.fsproj +3 -2
  249. data/tracks/fsharp/exercises/isogram/Example.fs +1 -1
  250. data/tracks/fsharp/exercises/isogram/Isogram.fs +1 -1
  251. data/tracks/fsharp/exercises/isogram/Isogram.fsproj +3 -2
  252. data/tracks/fsharp/exercises/isogram/IsogramTest.fs +16 -40
  253. data/tracks/fsharp/exercises/kindergarten-garden/Example.fs +6 -4
  254. data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGarden.fs +3 -5
  255. data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGarden.fsproj +3 -2
  256. data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGardenTest.fs +100 -47
  257. data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProduct.fsproj +3 -2
  258. data/tracks/fsharp/exercises/leap/Example.fs +2 -2
  259. data/tracks/fsharp/exercises/leap/Leap.fs +2 -2
  260. data/tracks/fsharp/exercises/leap/Leap.fsproj +3 -2
  261. data/tracks/fsharp/exercises/leap/LeapTest.fs +19 -15
  262. data/tracks/fsharp/exercises/ledger/Ledger.fsproj +3 -2
  263. data/tracks/fsharp/exercises/lens-person/LensPerson.fsproj +3 -2
  264. data/tracks/fsharp/exercises/linked-list/LinkedList.fsproj +3 -2
  265. data/tracks/fsharp/exercises/list-ops/ListOps.fsproj +3 -2
  266. data/tracks/fsharp/exercises/luhn/Luhn.fsproj +3 -2
  267. data/tracks/fsharp/exercises/luhn/LuhnTest.fs +30 -65
  268. data/tracks/fsharp/exercises/markdown/Markdown.fsproj +3 -2
  269. data/tracks/fsharp/exercises/matrix/Matrix.fsproj +3 -2
  270. data/tracks/fsharp/exercises/meetup/Meetup.fsproj +3 -2
  271. data/tracks/fsharp/exercises/minesweeper/Example.fs +9 -11
  272. data/tracks/fsharp/exercises/minesweeper/Minesweeper.fsproj +3 -2
  273. data/tracks/fsharp/exercises/minesweeper/MinesweeperTest.fs +117 -80
  274. data/tracks/fsharp/exercises/nth-prime/NthPrime.fsproj +3 -2
  275. data/tracks/fsharp/exercises/nucleotide-count/NucleotideCount.fsproj +3 -2
  276. data/tracks/fsharp/exercises/ocr-numbers/OcrNumbers.fsproj +3 -2
  277. data/tracks/fsharp/exercises/palindrome-products/PalindromeProducts.fsproj +3 -2
  278. data/tracks/fsharp/exercises/pangram/Pangram.fsproj +3 -2
  279. data/tracks/fsharp/exercises/pangram/PangramTest.fs +15 -27
  280. data/tracks/fsharp/exercises/parallel-letter-frequency/ParallelLetterFrequency.fsproj +3 -2
  281. data/tracks/fsharp/exercises/pascals-triangle/PascalsTriangle.fsproj +3 -2
  282. data/tracks/fsharp/exercises/perfect-numbers/PerfectNumbers.fsproj +3 -2
  283. data/tracks/fsharp/exercises/phone-number/PhoneNumber.fsproj +3 -2
  284. data/tracks/fsharp/exercises/pig-latin/Example.fs +1 -1
  285. data/tracks/fsharp/exercises/pig-latin/PigLatin.fsproj +3 -2
  286. data/tracks/fsharp/exercises/pig-latin/PigLatinTest.fs +64 -26
  287. data/tracks/fsharp/exercises/poker/Poker.fsproj +3 -2
  288. data/tracks/fsharp/exercises/pov/Pov.fsproj +3 -2
  289. data/tracks/fsharp/exercises/prime-factors/PrimeFactors.fsproj +3 -2
  290. data/tracks/fsharp/exercises/protein-translation/ProteinTranslation.fsproj +3 -2
  291. data/tracks/fsharp/exercises/proverb/Proverb.fsproj +3 -2
  292. data/tracks/fsharp/exercises/pythagorean-triplet/PythagoreanTriplet.fsproj +3 -2
  293. data/tracks/fsharp/exercises/queen-attack/Example.fs +3 -1
  294. data/tracks/fsharp/exercises/queen-attack/QueenAttack.fs +2 -0
  295. data/tracks/fsharp/exercises/queen-attack/QueenAttack.fsproj +3 -2
  296. data/tracks/fsharp/exercises/queen-attack/QueenAttackTest.fs +50 -20
  297. data/tracks/fsharp/exercises/rail-fence-cipher/RailFenceCipher.fsproj +3 -2
  298. data/tracks/fsharp/exercises/raindrops/Raindrops.fsproj +3 -2
  299. data/tracks/fsharp/exercises/raindrops/RaindropsTest.fs +77 -37
  300. data/tracks/fsharp/exercises/react/React.fsproj +3 -2
  301. data/tracks/fsharp/exercises/rectangles/Rectangles.fsproj +3 -2
  302. data/tracks/fsharp/exercises/rna-transcription/Example.fs +15 -7
  303. data/tracks/fsharp/exercises/rna-transcription/RnaTranscription.fs +2 -2
  304. data/tracks/fsharp/exercises/rna-transcription/RnaTranscription.fsproj +3 -2
  305. data/tracks/fsharp/exercises/rna-transcription/RnaTranscriptionTest.fs +29 -14
  306. data/tracks/fsharp/exercises/robot-name/RobotName.fsproj +3 -2
  307. data/tracks/fsharp/exercises/robot-simulator/RobotSimulator.fsproj +3 -2
  308. data/tracks/fsharp/exercises/roman-numerals/Example.fs +2 -2
  309. data/tracks/fsharp/exercises/roman-numerals/RomanNumerals.fs +2 -2
  310. data/tracks/fsharp/exercises/roman-numerals/RomanNumerals.fsproj +3 -2
  311. data/tracks/fsharp/exercises/roman-numerals/RomanNumeralsTest.fs +79 -26
  312. data/tracks/fsharp/exercises/run-length-encoding/RunLengthEncoding.fsproj +3 -2
  313. data/tracks/fsharp/exercises/saddle-points/SaddlePoints.fsproj +3 -2
  314. data/tracks/fsharp/exercises/say/Say.fsproj +3 -2
  315. data/tracks/fsharp/exercises/scale-generator/ScaleGenerator.fsproj +3 -2
  316. data/tracks/fsharp/exercises/scrabble-score/ScrabbleScore.fsproj +3 -2
  317. data/tracks/fsharp/exercises/scrabble-score/ScrabbleScoreTest.fs +33 -17
  318. data/tracks/fsharp/exercises/secret-handshake/SecretHandshake.fsproj +3 -2
  319. data/tracks/fsharp/exercises/series/Series.fsproj +3 -2
  320. data/tracks/fsharp/exercises/sgf-parsing/SgfParsing.fsproj +3 -2
  321. data/tracks/fsharp/exercises/sieve/Sieve.fsproj +3 -2
  322. data/tracks/fsharp/exercises/simple-cipher/SimpleCipher.fsproj +3 -2
  323. data/tracks/fsharp/exercises/simple-linked-list/SimpleLinkedList.fsproj +3 -2
  324. data/tracks/fsharp/exercises/space-age/SpaceAge.fsproj +3 -2
  325. data/tracks/fsharp/exercises/strain/Strain.fsproj +3 -2
  326. data/tracks/fsharp/exercises/sublist/Sublist.fsproj +3 -2
  327. data/tracks/fsharp/exercises/sum-of-multiples/SumOfMultiples.fsproj +3 -2
  328. data/tracks/fsharp/exercises/tournament/Tournament.fsproj +3 -2
  329. data/tracks/fsharp/exercises/transpose/Transpose.fsproj +3 -2
  330. data/tracks/fsharp/exercises/tree-building/TreeBuilding.fsproj +3 -2
  331. data/tracks/fsharp/exercises/triangle/Triangle.fsproj +3 -2
  332. data/tracks/fsharp/exercises/twelve-days/TwelveDays.fsproj +3 -2
  333. data/tracks/fsharp/exercises/two-bucket/TwoBucket.fsproj +3 -2
  334. data/tracks/fsharp/exercises/two-fer/TwoFer.fsproj +3 -2
  335. data/tracks/fsharp/exercises/variable-length-quantity/VariableLengthQuantity.fsproj +3 -2
  336. data/tracks/fsharp/exercises/word-count/WordCount.fsproj +3 -2
  337. data/tracks/fsharp/exercises/word-search/WordSearch.fsproj +3 -2
  338. data/tracks/fsharp/exercises/wordy/Wordy.fsproj +3 -2
  339. data/tracks/fsharp/exercises/zebra-puzzle/ZebraPuzzle.fsproj +3 -2
  340. data/tracks/fsharp/exercises/zipper/Zipper.fsproj +3 -2
  341. data/tracks/fsharp/generators/Common.fs +96 -0
  342. data/tracks/fsharp/generators/Exercise.fs +250 -0
  343. data/tracks/fsharp/generators/Generators.fs +210 -0
  344. data/tracks/fsharp/generators/Generators.fsproj +32 -0
  345. data/tracks/fsharp/generators/Generators.sln +24 -0
  346. data/tracks/fsharp/generators/Input.fs +99 -0
  347. data/tracks/fsharp/generators/Options.fs +31 -0
  348. data/tracks/fsharp/generators/Output.fs +224 -0
  349. data/tracks/fsharp/generators/Program.fs +35 -0
  350. data/tracks/fsharp/generators/Properties/launchSettings.json +8 -0
  351. data/tracks/fsharp/generators/Templates/_AssertEmpty.liquid +1 -0
  352. data/tracks/fsharp/generators/Templates/_AssertEqual.liquid +1 -0
  353. data/tracks/fsharp/generators/Templates/_TestClass.liquid +13 -0
  354. data/tracks/fsharp/generators/Templates/_TestMethod.liquid +3 -0
  355. data/tracks/fsharp/generators/Templates/_TestMethodBody.liquid +4 -0
  356. data/tracks/go/.travis.yml +3 -3
  357. data/tracks/groovy/CONTRIBUTING.md +2 -2
  358. data/tracks/groovy/config.json +12 -0
  359. data/tracks/groovy/exercises/scrabble-score/Example.groovy +18 -0
  360. data/tracks/groovy/exercises/scrabble-score/README.md +63 -0
  361. data/tracks/groovy/exercises/scrabble-score/ScrabbleScore.groovy +7 -0
  362. data/tracks/groovy/exercises/scrabble-score/ScrabbleScoreSpec.groovy +45 -0
  363. data/tracks/groovy/exercises/two-fer/TwoFer.groovy +2 -2
  364. data/tracks/haskell/exercises/change/README.md +1 -1
  365. data/tracks/haskell/exercises/lens-person/README.md +1 -1
  366. data/tracks/haskell/exercises/palindrome-products/README.md +5 -12
  367. data/tracks/haskell/exercises/sum-of-multiples/README.md +0 -3
  368. data/tracks/idris/config.json +12 -0
  369. data/tracks/idris/exercises/accumulate/Accumulate.ipkg +5 -0
  370. data/tracks/idris/exercises/accumulate/Makefile +23 -0
  371. data/tracks/idris/exercises/accumulate/README.md +32 -0
  372. data/tracks/idris/exercises/accumulate/src/Example.idr +6 -0
  373. data/tracks/idris/exercises/accumulate/src/Test/Accumulate.idr +35 -0
  374. data/tracks/java/config/maintainers.json +4 -7
  375. data/tracks/java/config.json +99 -22
  376. data/tracks/java/exercises/binary-search-tree/.meta/src/reference/java/{BST.java → BinarySearchTree.java} +1 -1
  377. data/tracks/java/exercises/binary-search-tree/src/test/java/{BSTTest.java → BinarySearchTreeTest.java} +34 -36
  378. data/tracks/java/exercises/robot-simulator/src/main/java/GridPosition.java +19 -15
  379. data/tracks/java/exercises/saddle-points/.meta/src/reference/java/MatrixCoordinate.java +7 -1
  380. data/tracks/java/exercises/saddle-points/src/main/java/MatrixCoordinate.java +7 -1
  381. data/tracks/java/exercises/settings.gradle +1 -0
  382. data/tracks/java/exercises/tournament/.meta/src/reference/java/Result.java +5 -0
  383. data/tracks/java/exercises/tournament/.meta/src/reference/java/TeamResult.java +41 -0
  384. data/tracks/java/exercises/tournament/.meta/src/reference/java/Tournament.java +62 -0
  385. data/tracks/java/exercises/tournament/README.md +78 -0
  386. data/tracks/java/exercises/tournament/build.gradle +18 -0
  387. data/tracks/java/{.Rhistory → exercises/tournament/src/main/java/.keep} +0 -0
  388. data/tracks/java/exercises/tournament/src/test/java/TournamentTest.java +160 -0
  389. data/tracks/php/config.json +14 -0
  390. data/tracks/php/exercises/collatz-conjecture/collatz-conjecture_test.php +44 -0
  391. data/tracks/php/exercises/collatz-conjecture/example.php +18 -0
  392. data/tracks/python/exercises/circular-buffer/circular_buffer.py +1 -1
  393. data/tracks/python/exercises/clock/clock.py +1 -1
  394. data/tracks/python/exercises/etl/etl.py +1 -1
  395. data/tracks/python/exercises/grade-school/grade_school.py +1 -1
  396. data/tracks/python/exercises/grains/grains.py +2 -2
  397. data/tracks/python/exercises/kindergarten-garden/kindergarten_garden.py +1 -1
  398. data/tracks/python/exercises/linked-list/linked_list.py +1 -1
  399. data/tracks/python/exercises/rectangles/rectangles.py +1 -1
  400. data/tracks/python/exercises/sum-of-multiples/sum_of_multiples.py +1 -1
  401. data/tracks/rust/exercises/bob/tests/bob.rs +1 -0
  402. data/tracks/rust/exercises/crypto-square/tests/crypto-square.rs +7 -0
  403. data/tracks/rust/exercises/gigasecond/tests/gigasecond.rs +1 -1
  404. data/tracks/rust/exercises/phone-number/Cargo.lock +1 -1
  405. data/tracks/rust/exercises/phone-number/Cargo.toml +1 -1
  406. data/tracks/rust/exercises/phone-number/example.rs +17 -23
  407. data/tracks/rust/exercises/phone-number/tests/phone-number.rs +31 -40
  408. data/tracks/rust/exercises/say/tests/say.rs +2 -0
  409. data/tracks/rust/exercises/sum-of-multiples/README.md +0 -3
  410. data/tracks/scala/config.json +11 -0
  411. data/tracks/scala/exercises/collatz-conjecture/README.md +43 -0
  412. data/tracks/scala/exercises/collatz-conjecture/build.sbt +3 -0
  413. data/tracks/scala/exercises/collatz-conjecture/example.scala +17 -0
  414. data/tracks/scala/exercises/collatz-conjecture/src/main/scala/.keep +0 -0
  415. data/tracks/scala/exercises/collatz-conjecture/src/test/scala/CollatzConjectureTest.scala +34 -0
  416. data/tracks/scala/testgen/src/main/scala/CollatzConjectureTestGenerator.scala +35 -0
  417. data/tracks/scheme/config.json +8 -0
  418. data/tracks/scheme/exercises/word-count/README.md +19 -0
  419. data/tracks/scheme/exercises/word-count/example.scm +27 -0
  420. data/tracks/scheme/exercises/word-count/word-count-test.scm +90 -0
  421. data/tracks/scheme/exercises/word-count/word-count.scm +5 -0
  422. data/tracks/sml/README.md +20 -1
  423. data/tracks/sml/bin/generate +74 -20
  424. data/tracks/sml/exercises/binary/README.md +23 -5
  425. data/tracks/sml/exercises/binary/binary.sml +2 -0
  426. data/tracks/sml/exercises/binary/example.sml +10 -21
  427. data/tracks/sml/exercises/binary/test.sml +55 -30
  428. data/tracks/sml/exercises/binary/testlib.sml +159 -0
  429. data/tracks/sml/exercises/flatten-array/HINTS.md +8 -0
  430. data/tracks/sml/exercises/flatten-array/README.md +31 -6
  431. data/tracks/sml/exercises/flatten-array/example.sml +3 -4
  432. data/tracks/sml/exercises/flatten-array/flatten-array.sml +4 -5
  433. data/tracks/sml/exercises/flatten-array/test.sml +76 -52
  434. data/tracks/sml/exercises/flatten-array/testlib.sml +159 -0
  435. data/tracks/sml/exercises/nth-prime/HINTS.md +9 -0
  436. data/tracks/sml/exercises/nth-prime/README.md +32 -5
  437. data/tracks/sml/exercises/nth-prime/example.sml +28 -46
  438. data/tracks/sml/exercises/nth-prime/nth-prime.sml +1 -1
  439. data/tracks/sml/exercises/nth-prime/test.sml +19 -63
  440. data/tracks/sml/exercises/nth-prime/testlib.sml +159 -0
  441. data/tracks/sml/exercises/raindrops/README.md +21 -5
  442. data/tracks/typescript/config.json +14 -0
  443. data/tracks/typescript/exercises/triangle/README.md +55 -0
  444. data/tracks/typescript/exercises/triangle/package.json +36 -0
  445. data/tracks/typescript/exercises/triangle/triangle.example.ts +56 -0
  446. data/tracks/typescript/exercises/triangle/triangle.test.ts +79 -0
  447. data/tracks/typescript/exercises/triangle/triangle.ts +12 -0
  448. data/tracks/typescript/exercises/triangle/tsconfig.json +22 -0
  449. data/tracks/typescript/exercises/triangle/tslint.json +127 -0
  450. data/tracks/typescript/exercises/triangle/yarn.lock +2305 -0
  451. metadata +85 -6
  452. data/tracks/d/exercises/crypto-square/.dub/dub.json +0 -6
@@ -5,26 +5,26 @@ fn to_some_string(s: &str) -> Option<String> {
5
5
  }
6
6
 
7
7
  #[test]
8
- fn test_number_cleans() {
9
- assert_eq!(phone::number("(123) 456-7890"), to_some_string("1234567890"));
8
+ fn test_cleans_the_number() {
9
+ assert_eq!(
10
+ phone::number("(223) 456-7890"),
11
+ to_some_string("2234567890")
12
+ );
10
13
  }
11
14
 
12
15
  #[test]
13
16
  #[ignore]
14
- fn test_number_cleans_with_dots() {
15
- assert_eq!(phone::number("123.456.7890"), to_some_string("1234567890"));
17
+ fn test_cleans_numbers_with_dots() {
18
+ assert_eq!(phone::number("223.456.7890"), to_some_string("2234567890"));
16
19
  }
17
20
 
18
21
  #[test]
19
22
  #[ignore]
20
- fn test_valid_when_11_digits_and_first_is_1() {
21
- assert_eq!(phone::number("11234567890"), to_some_string("1234567890"));
22
- }
23
-
24
- #[test]
25
- #[ignore]
26
- fn test_invalid_when_11_digits() {
27
- assert_eq!(phone::number("21234567890"), None);
23
+ fn test_cleans_numbers_with_multiple_spaces() {
24
+ assert_eq!(
25
+ phone::number("223 456 7890 "),
26
+ to_some_string("2234567890")
27
+ );
28
28
  }
29
29
 
30
30
  #[test]
@@ -35,60 +35,51 @@ fn test_invalid_when_9_digits() {
35
35
 
36
36
  #[test]
37
37
  #[ignore]
38
- fn test_invalid_when_empty() {
39
- assert_eq!(phone::number(""), None);
40
- }
41
-
42
- #[test]
43
- #[ignore]
44
- fn test_invalid_when_no_digits_present() {
45
- assert_eq!(phone::number(" (-) "), None);
46
- }
47
-
48
- #[test]
49
- #[ignore]
50
- fn test_valid_with_leading_characters() {
51
- assert_eq!(phone::number("my number is 123 456 7890"), to_some_string("1234567890"));
38
+ fn test_invalid_when_11_digits_does_not_start_with_a_1() {
39
+ assert_eq!(phone::number("22234567890"), None);
52
40
  }
53
41
 
54
42
  #[test]
55
43
  #[ignore]
56
- fn test_valid_with_trailing_characters() {
57
- assert_eq!(phone::number("123 456 7890 - bob"), to_some_string("1234567890"));
44
+ fn test_valid_when_11_digits_and_starting_with_1() {
45
+ assert_eq!(phone::number("12234567890"), to_some_string("2234567890"));
58
46
  }
59
47
 
60
48
  #[test]
61
49
  #[ignore]
62
- fn test_area_code() {
63
- assert_eq!(phone::area_code("1234567890"), to_some_string("123"));
50
+ fn test_valid_when_11_digits_and_starting_with_1_even_with_punctuation() {
51
+ assert_eq!(
52
+ phone::number("+1 (223) 456-7890"),
53
+ to_some_string("2234567890")
54
+ );
64
55
  }
65
56
 
66
57
  #[test]
67
58
  #[ignore]
68
- fn test_area_code_with_full_us_phone_number() {
69
- assert_eq!(phone::area_code("18234567890"), to_some_string("823"));
59
+ fn test_invalid_when_more_than_11_digits() {
60
+ assert_eq!(phone::number("321234567890"), None);
70
61
  }
71
62
 
72
63
  #[test]
73
64
  #[ignore]
74
- fn test_area_code_with_invalid() {
75
- assert_eq!(phone::area_code("1234161567890"), None);
65
+ fn test_invalid_with_letters() {
66
+ assert_eq!(phone::number("123-abc-7890"), None);
76
67
  }
77
68
 
78
69
  #[test]
79
70
  #[ignore]
80
- fn test_pretty_print() {
81
- assert_eq!(phone::pretty_print("1234567890"), "(123) 456-7890");
71
+ fn test_invalid_with_punctuations() {
72
+ assert_eq!(phone::number("123-@:!-7890"), None);
82
73
  }
83
74
 
84
75
  #[test]
85
76
  #[ignore]
86
- fn test_pretty_print_with_full_us_phone_number() {
87
- assert_eq!(phone::pretty_print("11234567890"), "(123) 456-7890");
77
+ fn test_invalid_if_area_code_does_not_start_with_2_9() {
78
+ assert_eq!(phone::number("(123) 456-7890"), None);
88
79
  }
89
80
 
90
81
  #[test]
91
82
  #[ignore]
92
- fn test_pretty_print_with_invalid() {
93
- assert_eq!(phone::pretty_print("1186234567890"), "invalid");
83
+ fn test_invalid_if_exchange_code_does_not_start_with_2_9() {
84
+ assert_eq!(phone::number("(223) 056-7890"), None);
94
85
  }
@@ -14,12 +14,14 @@ fn test_zero() {
14
14
  //
15
15
  /*
16
16
  #[test]
17
+ #[ignore]
17
18
  fn test_negative() {
18
19
  assert_eq!(say::encode(-1), String::from("won't compile"));
19
20
  }
20
21
  */
21
22
 
22
23
  #[test]
24
+ #[ignore]
23
25
  fn test_one() {
24
26
  assert_eq!(say::encode(1), String::from("one"));
25
27
  }
@@ -8,9 +8,6 @@ multiples of either 3 or 5, we get 3, 5, 6 and 9, 10, 12, 15, and 18.
8
8
 
9
9
  The sum of these multiples is 78.
10
10
 
11
- Given a number, find the sum of the multiples of a given set of numbers,
12
- up to but not including that number.
13
-
14
11
  ## Rust Installation
15
12
 
16
13
  Refer to the [exercism help page][help-page] for Rust installation and learning
@@ -82,6 +82,17 @@
82
82
  "Transforming"
83
83
  ]
84
84
  },
85
+ {
86
+ "uuid": "65a76aba-a485-222d-84ba-e9a445b25be6",
87
+ "slug": "collatz-conjecture",
88
+ "core": true,
89
+ "unlocked_by": "leap",
90
+ "difficulty": 2,
91
+ "topics": [
92
+ "Recursion",
93
+ "Mathematics"
94
+ ]
95
+ },
85
96
  {
86
97
  "uuid": "5a31217f-02fd-4be4-b64f-7a93f36f5140",
87
98
  "slug": "hamming",
@@ -0,0 +1,43 @@
1
+ ## Collatz Conjecture.
2
+
3
+ The Collatz Conjecture or 3x+1 problem can be summarized as follows:
4
+
5
+ Take any positive integer n. If n is even, divide n by 2 to get n / 2. If n is
6
+ odd, multiply n by 3 and add 1 to get 3n + 1. Repeat the process indefinitely.
7
+ The conjecture states that no matter which number you start with, you will
8
+ always reach 1 eventually.
9
+
10
+ Given a number n, return the number of steps required to reach 1.
11
+
12
+ ## Examples
13
+ Starting with n = 12, the steps would be as follows:
14
+
15
+ 0. 12
16
+ 1. 6
17
+ 2. 3
18
+ 3. 10
19
+ 4. 5
20
+ 5. 16
21
+ 6. 8
22
+ 7. 4
23
+ 8. 2
24
+ 9. 1
25
+
26
+ Resulting in 9 steps. So for input n = 12, the return value would be 9.
27
+
28
+ The Scala exercises assume an SBT project scheme. The exercise solution source
29
+ should be placed within the exercise directory/src/main/scala. The exercise
30
+ unit tests can be found within the exercise directory/src/test/scala.
31
+
32
+ To run the tests simply run the command `sbt test` in the exercise directory.
33
+
34
+ For more detailed info about the Scala track see the [help
35
+ page](http://exercism.io/languages/scala).
36
+
37
+ ## Source
38
+
39
+ An unsolved problem in mathematics named after mathematician Lothar Collatz
40
+ see more at [collatz conjecture wikipedia](https://en.wikipedia.org/wiki/3x_%2B_1_problem)
41
+
42
+ ## Submitting Incomplete Solutions
43
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,3 @@
1
+ scalaVersion := "2.11.7"
2
+
3
+ libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.5" % "test"
@@ -0,0 +1,17 @@
1
+ object CollatzConjecture {
2
+
3
+ def isEven( v:Int ): Boolean = v % 2 == 0
4
+
5
+ def collatz_h(n: Int, acc: Int): Option[Int] = {
6
+ if (n <= 0)
7
+ None
8
+ else if (n == 1){
9
+ Some(acc)
10
+ } else if (isEven(n)){
11
+ collatz_h(n/2, acc+1)
12
+ } else{
13
+ collatz_h(n*3 + 1, acc+1)}
14
+ }
15
+
16
+ def steps(n: Int): Option[Int] = collatz_h(n, 0)
17
+ }
@@ -0,0 +1,34 @@
1
+ import org.scalatest.{Matchers, FunSuite}
2
+
3
+ /** @version 1.1.1 */
4
+ class CollatzConjectureTest extends FunSuite with Matchers {
5
+
6
+ test("zero steps for one") {
7
+ CollatzConjecture.steps(1) should be (Some(0))
8
+ }
9
+
10
+ test("divide if even") {
11
+ pending
12
+ CollatzConjecture.steps(16) should be (Some(4))
13
+ }
14
+
15
+ test("even and odd steps") {
16
+ pending
17
+ CollatzConjecture.steps(12) should be (Some(9))
18
+ }
19
+
20
+ test("Large number of even and odd steps") {
21
+ pending
22
+ CollatzConjecture.steps(1000000) should be (Some(152))
23
+ }
24
+
25
+ test("zero is an error") {
26
+ pending
27
+ CollatzConjecture.steps(0) should be (None)
28
+ }
29
+
30
+ test("negative value is an error") {
31
+ pending
32
+ CollatzConjecture.steps(-15) should be (None)
33
+ }
34
+ }
@@ -0,0 +1,35 @@
1
+ import java.io.File
2
+
3
+ import testgen.TestSuiteBuilder._
4
+ import testgen._
5
+
6
+ object CollatzConjectureTestGenerator {
7
+ def main(args: Array[String]): Unit = {
8
+ val file = new File("src/main/resources/collatz-conjecture.json")
9
+
10
+ def toString(expected: CanonicalDataParser.Expected): String = {
11
+ expected match {
12
+ case Left(_) => "None"
13
+ case Right(null) => "None"
14
+ case Right(n) => s"Some($n)"
15
+ }
16
+ }
17
+
18
+ def fromLabeledTest(argNames: String*): ToTestCaseData =
19
+ withLabeledTest { sut =>
20
+ labeledTest =>
21
+ val args = sutArgs(labeledTest.result, argNames: _*)
22
+ val property = labeledTest.property
23
+ val sutCall =
24
+ s"""$sut.$property($args)"""
25
+ val expected = toString(labeledTest.expected)
26
+ TestCaseData(labeledTest.description, sutCall, expected)
27
+ }
28
+
29
+ val code = TestSuiteBuilder.build(file, fromLabeledTest("number"))
30
+
31
+ println(s"-------------")
32
+ println(code)
33
+ println(s"-------------")
34
+ }
35
+ }
@@ -112,6 +112,14 @@
112
112
  "topics": null,
113
113
  "unlocked_by": null,
114
114
  "uuid": "5b44ccd4-b1f4-4b86-89c8-f1dec5905ccb"
115
+ },
116
+ {
117
+ "core": false,
118
+ "difficulty": 1,
119
+ "slug": "word-count",
120
+ "topics": null,
121
+ "unlocked_by": null,
122
+ "uuid": "9460b65d-dc80-4a95-8782-b395d2cc979e"
115
123
  }
116
124
  ],
117
125
  "foregone": [],
@@ -0,0 +1,19 @@
1
+ # Word Count
2
+
3
+ Given a phrase, count the occurrences of each word in that phrase.
4
+
5
+ For example, given the input `"olly olly in come free"`
6
+
7
+ ```plain
8
+ olly: 2
9
+ in: 1
10
+ come: 1
11
+ free: 1
12
+ ```
13
+
14
+ ## Source
15
+
16
+ This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour.
17
+
18
+ ## Submitting Incomplete Solutions
19
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,27 @@
1
+ (define-module (word-count)
2
+ #:use-module (srfi srfi-1)
3
+ #:use-module (ice-9 regex)
4
+ #:export (countwords))
5
+
6
+
7
+ (define (countword word counters)
8
+ (let* ((oldcount (assoc-ref counters word))
9
+ (newcount (if oldcount (+ oldcount 1) 1)))
10
+ (assoc-set! counters word newcount)))
11
+
12
+
13
+ (define (replace text pattern replacement)
14
+ (regexp-substitute/global #f pattern text 'pre replacement 'post))
15
+
16
+
17
+ (define (normalize phrase)
18
+ (let* ((nopuncts (replace phrase "[.,\n!&@%:^$]" " "))
19
+ (onespace (replace nopuncts "[ ]+" " "))
20
+ (endspace (replace onespace "[ ]+$" ""))
21
+ (noquotes (replace endspace "( ')|(' )" " ")))
22
+ (string-downcase noquotes)))
23
+
24
+
25
+ (define (countwords phrase)
26
+ (fold countword '()
27
+ (string-split (normalize phrase) #\space)))
@@ -0,0 +1,90 @@
1
+ ;; Load SRFI-64 lightweight testing specification
2
+ (use-modules (srfi srfi-64))
3
+
4
+ ;; Suppress log file output. To write logs, comment out the following line:
5
+ (module-define! (resolve-module '(srfi srfi-64)) 'test-log-to-file #f)
6
+
7
+ ;; Require module
8
+ (add-to-load-path (dirname (current-filename)))
9
+ (use-modules (word-count))
10
+
11
+ ;; Tests for countwords
12
+ (test-begin "countwords")
13
+
14
+
15
+ (test-equal "count one word"
16
+ (assoc-ref (countwords "word") "word") 1)
17
+
18
+
19
+ (test-assert "count one of each word"
20
+ (let ((result (countwords "one of each")))
21
+ (and (equal? (assoc-ref result "one") 1)
22
+ (equal? (assoc-ref result "of") 1)
23
+ (equal? (assoc-ref result "each") 1))))
24
+
25
+
26
+ (test-assert "multiple occurrences of a word"
27
+ (let ((result (countwords "one fish two fish red fish blue fish")))
28
+ (and (equal? (assoc-ref result "one") 1)
29
+ (equal? (assoc-ref result "fish") 4)
30
+ (equal? (assoc-ref result "two") 1)
31
+ (equal? (assoc-ref result "red") 1)
32
+ (equal? (assoc-ref result "blue") 1))))
33
+
34
+
35
+ (test-assert "handles cramped lists"
36
+ (let ((result (countwords "one,two,three")))
37
+ (and (equal? (assoc-ref result "one") 1)
38
+ (equal? (assoc-ref result "two") 1)
39
+ (equal? (assoc-ref result "three") 1))))
40
+
41
+
42
+ (test-assert "handles expanded lists"
43
+ (let ((result (countwords "one,\ntwo,\nthree")))
44
+ (and (equal? (assoc-ref result "one") 1)
45
+ (equal? (assoc-ref result "two") 1)
46
+ (equal? (assoc-ref result "three") 1))))
47
+
48
+
49
+ (test-assert "ignore punctuation"
50
+ (let ((result (countwords "car: carpet as java: javascript!!&@$%^&")))
51
+ (and (equal? (assoc-ref result "car") 1)
52
+ (equal? (assoc-ref result "carpet") 1)
53
+ (equal? (assoc-ref result "as") 1)
54
+ (equal? (assoc-ref result "java") 1)
55
+ (equal? (assoc-ref result "javascript") 1))))
56
+
57
+
58
+ (test-assert "include numbers"
59
+ (let ((result (countwords "testing, 1, 2 testing")))
60
+ (and (equal? (assoc-ref result "testing") 2)
61
+ (equal? (assoc-ref result "1") 1)
62
+ (equal? (assoc-ref result "2") 1))))
63
+
64
+
65
+ (test-assert "normalize case"
66
+ (let ((result (countwords "go Go GO Stop stop")))
67
+ (and (equal? (assoc-ref result "go") 3)
68
+ (equal? (assoc-ref result "stop") 2))))
69
+
70
+
71
+ (test-assert "with apostrophes"
72
+ (let ((result (countwords "First: don't laugh. Then: don't cry.")))
73
+ (and (equal? (assoc-ref result "first") 1)
74
+ (equal? (assoc-ref result "don't") 2)
75
+ (equal? (assoc-ref result "laugh") 1)
76
+ (equal? (assoc-ref result "then") 1)
77
+ (equal? (assoc-ref result "cry") 1))))
78
+
79
+
80
+ (test-assert "with quotations"
81
+ (let ((result (countwords "Joe can't tell between 'large' and large.")))
82
+ (and (equal? (assoc-ref result "joe") 1)
83
+ (equal? (assoc-ref result "can't") 1)
84
+ (equal? (assoc-ref result "tell") 1)
85
+ (equal? (assoc-ref result "between") 1)
86
+ (equal? (assoc-ref result "large") 2)
87
+ (equal? (assoc-ref result "and") 1))))
88
+
89
+
90
+ (test-end "countwords")
@@ -0,0 +1,5 @@
1
+ (define-module (word-count)
2
+ #:export (countwords))
3
+
4
+ (define (countwords phrase)
5
+ '())
data/tracks/sml/README.md CHANGED
@@ -91,11 +91,30 @@ bin/generate {{ slug }}
91
91
 
92
92
  It will create the exercise directory, test and stub files.
93
93
 
94
+ ### Generator
95
+
96
+ ```
97
+ usage: generate [-h] [--force] [--test-only] [--stub-only] [--example-only]
98
+ exercises [exercises ...]
99
+
100
+ positional arguments:
101
+ exercises
102
+
103
+ optional arguments:
104
+ -h, --help show this help message and exit
105
+ --force Type inference will be disabled and "string" will be
106
+ assumed. Test cases will need to be modified to match the
107
+ right data type.
108
+ --test-only Generate only "test.sml"
109
+ --stub-only Generate only "<exercise>.sml"
110
+ --example-only Generate only "example.sml"
111
+ ```
112
+
94
113
  **Note:**
95
114
  - You need Python 3.5+.
96
115
  - It may fail with some exercises. Reasons:
97
116
  - `canonical-data.json` does not exist
98
- - type mismatch
117
+ - type mismatch (in these situation you can use `--force` option)
99
118
 
100
119
  In those cases you will have to create the files manually. `testlib.sml` can be copied from `lib/testlib.sml`. When in doubt, feel free to open an issue.
101
120
 
@@ -42,7 +42,9 @@ def camelize(s):
42
42
  return re.sub('[-_](\w)', lambda x: x.group(1).upper(), s)
43
43
 
44
44
 
45
- def sml_type(value):
45
+ def sml_type(value, force=False):
46
+ if force:
47
+ return 'string'
46
48
  if value is None:
47
49
  return 'option'
48
50
  if isinstance(value, list):
@@ -72,7 +74,9 @@ def sml_type(value):
72
74
  return types[type(value)]
73
75
 
74
76
 
75
- def sml_value(value, smltype=''):
77
+ def sml_value(value, smltype='', force=False):
78
+ if force:
79
+ return json.dumps(value)
76
80
  if value is None:
77
81
  return 'NONE'
78
82
  _value = None
@@ -104,12 +108,12 @@ def get_fn_args(case):
104
108
  )
105
109
 
106
110
 
107
- def extract_signatures(data):
111
+ def extract_signatures(data, force=False):
108
112
  funcs = OrderedDict()
109
113
  exercise = data['exercise']
110
114
 
111
115
  def type_aux(values):
112
- s = {sml_type(val) for val in values}
116
+ s = {sml_type(val, force=force) for val in values}
113
117
  if len(s) == 1:
114
118
  return s.pop()
115
119
  if len(s) == 2 and 'option' in s:
@@ -136,10 +140,10 @@ def extract_signatures(data):
136
140
  else:
137
141
  # assumes there's at least one test with non "nullish" vars
138
142
  fn = camelize(case.get('property', exercise))
139
- if sml_type(case['expected']) == 'exn':
143
+ if sml_type(case['expected'], force=force) == 'exn':
140
144
  continue
141
145
  args = get_fn_args(case)
142
- if not all(args.values()) or sml_type(case['expected']) == "'a list":# or not case['expected']:
146
+ if not all(args.values()) or sml_type(case['expected'], force=force) == "'a list":# or not case['expected']:
143
147
  continue
144
148
  funcs.setdefault(fn, []).append({
145
149
  'args': args,
@@ -150,17 +154,17 @@ def extract_signatures(data):
150
154
  return {fn: signature(funcs[fn]) for fn in funcs}
151
155
 
152
156
 
153
- def expectation(signature, fn, args, expected):
157
+ def expectation(signature, fn, args, expected, force=False):
154
158
  tmpl = '(fn _ => %s |> Expect.%s)'
155
- output = sml_value(expected, signature['output'])
159
+ output = sml_value(expected, signature['output'], force=force)
156
160
  invocation = '%s (%s)' % (
157
161
  fn,
158
162
  ', '.join((
159
- sml_value(val, signature['args'][arg])
163
+ sml_value(val, signature['args'][arg], force=force)
160
164
  for arg, val in args.items())
161
165
  )
162
166
  )
163
- if sml_type(expected) == 'exn':
167
+ if sml_type(expected, force=force) == 'exn':
164
168
  return tmpl % (
165
169
  '(fn _ => %s)' % invocation,
166
170
  'error (%s)' % output
@@ -181,7 +185,7 @@ def expectation(signature, fn, args, expected):
181
185
  )
182
186
 
183
187
 
184
- def generate_test_content(data, signature):
188
+ def generate_test_content(data, signature, force=False):
185
189
  exercise = data['exercise']
186
190
 
187
191
  def fmt(case, depth=0):
@@ -192,7 +196,7 @@ def generate_test_content(data, signature):
192
196
  args = get_fn_args(case)
193
197
  return '\n'.join((
194
198
  indent(depth, 'test "%s"' % case.get('description', fn)),
195
- indent(depth + 2, expectation(signature[fn], fn, args, expected))
199
+ indent(depth + 2, expectation(signature[fn], fn, args, expected, force=force))
196
200
  ))
197
201
 
198
202
  def traverse(cases, depth=0):
@@ -247,17 +251,33 @@ def write(path, content):
247
251
  f.write(content)
248
252
 
249
253
 
250
- def generate(exercise):
254
+ # flags
255
+ TEST = 1
256
+ STUB = 2
257
+ EXAMPLE = 4
258
+ FLAGS = TEST | STUB | EXAMPLE
259
+
260
+
261
+ def generate(exercise, flags, force=False):
251
262
  root = Path(__file__).parent.parent.absolute()
252
263
  path = root / 'exercises' / exercise
264
+
253
265
  if not path.exists():
254
266
  path.mkdir()
267
+
255
268
  data = fetch(exercise)
256
- signatures = extract_signatures(data)
257
- write(path / 'test.sml', generate_test_content(data, signatures))
269
+ signatures = extract_signatures(data, force=force)
258
270
  content = generate_exercise_content(signatures)
259
- write(path / ('%s.sml' % exercise), content)
260
- write(path / 'example.sml', content)
271
+
272
+ if flags & TEST:
273
+ write(path / 'test.sml', generate_test_content(data, signatures, force=force))
274
+
275
+ if flags & STUB:
276
+ write(path / ('%s.sml' % exercise), content)
277
+
278
+ if flags & EXAMPLE:
279
+ write(path / 'example.sml', content)
280
+
261
281
  shutil.copyfile(
262
282
  (root / 'lib/testlib.sml').as_posix(),
263
283
  (path / 'testlib.sml').as_posix()
@@ -265,11 +285,45 @@ def generate(exercise):
265
285
 
266
286
 
267
287
  if __name__ == '__main__':
268
- import sys
288
+ import argparse
289
+
290
+ parser = argparse.ArgumentParser()
291
+ parser.add_argument('exercises', nargs='+')
292
+ parser.add_argument(
293
+ '--force',
294
+ action='store_true',
295
+ help=(
296
+ 'Type inference will be disabled and "string" will be assumed. ' +
297
+ 'Test cases will need to be modified to match the right data type.'
298
+ )
299
+ )
300
+ parser.add_argument(
301
+ '--test-only',
302
+ action='store_true',
303
+ help='Generate only "test.sml"'
304
+ )
305
+ parser.add_argument(
306
+ '--stub-only',
307
+ action='store_true',
308
+ help='Generate only "<exercise>.sml"'
309
+ )
310
+ parser.add_argument(
311
+ '--example-only',
312
+ action='store_true',
313
+ help='Generate only "example.sml"'
314
+ )
315
+ args = parser.parse_args()
269
316
 
270
- for exercise in sys.argv[1:]:
317
+ for exercise in args.exercises:
271
318
  try:
272
- generate(exercise)
319
+ flags = 0
320
+ if args.test_only:
321
+ flags |= ~(STUB | EXAMPLE)
322
+ if args.example_only:
323
+ flags |= ~(STUB | TEST)
324
+ if args.stub_only:
325
+ flags |= ~(TEST | EXAMPLE)
326
+ generate(exercise, force=args.force, flags=flags or FLAGS)
273
327
  except FileNotFoundError:
274
328
  print('[%s]: canonical-data.json not found' % exercise)
275
329
  except Exception as e: