trackler 2.2.0.4 → 2.2.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (486) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/bash/config.json +10 -2
  4. data/tracks/bash/exercises/word-count/example.awk +12 -0
  5. data/tracks/bash/exercises/word-count/example.sh +21 -0
  6. data/tracks/c/config.json +0 -2
  7. data/tracks/ceylon/config.json +0 -2
  8. data/tracks/{erlang/exercises/all-your-base/.meta/readme.go.tmpl → clojure/config/exercise_readme.go.tmpl} +0 -1
  9. data/tracks/clojure/exercises/accumulate/README.md +35 -0
  10. data/tracks/clojure/exercises/acronym/README.md +15 -0
  11. data/tracks/clojure/exercises/all-your-base/README.md +35 -0
  12. data/tracks/clojure/exercises/allergies/README.md +37 -0
  13. data/tracks/clojure/exercises/anagram/README.md +13 -0
  14. data/tracks/clojure/exercises/atbash-cipher/README.md +34 -0
  15. data/tracks/clojure/exercises/bank-account/README.md +30 -0
  16. data/tracks/clojure/exercises/beer-song/README.md +327 -0
  17. data/tracks/clojure/exercises/binary/README.md +35 -0
  18. data/tracks/clojure/exercises/binary-search/README.md +41 -0
  19. data/tracks/clojure/exercises/binary-search-tree/README.md +60 -0
  20. data/tracks/clojure/exercises/bob/README.md +18 -0
  21. data/tracks/clojure/exercises/bracket-push/README.md +10 -0
  22. data/tracks/clojure/exercises/change/README.md +23 -0
  23. data/tracks/clojure/exercises/clock/README.md +13 -0
  24. data/tracks/clojure/exercises/crypto-square/README.md +74 -0
  25. data/tracks/clojure/exercises/difference-of-squares/README.md +19 -0
  26. data/tracks/clojure/exercises/etl/README.md +51 -0
  27. data/tracks/clojure/exercises/flatten-array/README.md +18 -0
  28. data/tracks/clojure/exercises/gigasecond/README.md +11 -0
  29. data/tracks/clojure/exercises/grade-school/README.md +42 -0
  30. data/tracks/clojure/exercises/grains/README.md +34 -0
  31. data/tracks/clojure/exercises/hamming/README.md +42 -0
  32. data/tracks/clojure/exercises/hello-world/README.md +51 -0
  33. data/tracks/clojure/exercises/hexadecimal/README.md +14 -0
  34. data/tracks/clojure/exercises/isogram/README.md +19 -0
  35. data/tracks/clojure/exercises/kindergarten-garden/README.md +66 -0
  36. data/tracks/clojure/exercises/largest-series-product/README.md +20 -0
  37. data/tracks/clojure/exercises/leap/README.md +33 -0
  38. data/tracks/clojure/exercises/luhn/README.md +71 -0
  39. data/tracks/clojure/exercises/meetup/README.md +30 -0
  40. data/tracks/clojure/exercises/minesweeper/README.md +30 -0
  41. data/tracks/clojure/exercises/nth-prime/README.md +15 -0
  42. data/tracks/clojure/exercises/nucleotide-count/README.md +33 -0
  43. data/tracks/clojure/exercises/octal/README.md +49 -0
  44. data/tracks/clojure/exercises/pangram/README.md +15 -0
  45. data/tracks/clojure/exercises/pascals-triangle/README.md +21 -0
  46. data/tracks/clojure/exercises/perfect-numbers/README.md +24 -0
  47. data/tracks/clojure/exercises/phone-number/README.md +34 -0
  48. data/tracks/clojure/exercises/pig-latin/README.md +24 -0
  49. data/tracks/clojure/exercises/pov/README.md +46 -0
  50. data/tracks/clojure/exercises/prime-factors/README.md +36 -0
  51. data/tracks/clojure/exercises/queen-attack/README.md +33 -0
  52. data/tracks/clojure/exercises/raindrops/README.md +24 -0
  53. data/tracks/clojure/exercises/rna-transcription/README.md +25 -0
  54. data/tracks/clojure/exercises/robot-name/README.md +22 -0
  55. data/tracks/clojure/exercises/robot-simulator/README.md +34 -0
  56. data/tracks/clojure/exercises/roman-numerals/README.md +49 -0
  57. data/tracks/clojure/exercises/rotational-cipher/README.md +36 -0
  58. data/tracks/clojure/exercises/scrabble-score/README.md +44 -0
  59. data/tracks/clojure/exercises/secret-handshake/README.md +35 -0
  60. data/tracks/clojure/exercises/sieve/README.md +34 -0
  61. data/tracks/clojure/exercises/space-age/README.md +24 -0
  62. data/tracks/clojure/exercises/strain/README.md +40 -0
  63. data/tracks/clojure/exercises/sublist/README.md +21 -0
  64. data/tracks/clojure/exercises/sum-of-multiples/README.md +18 -0
  65. data/tracks/clojure/exercises/triangle/README.md +26 -0
  66. data/tracks/clojure/exercises/trinary/README.md +28 -0
  67. data/tracks/clojure/exercises/word-count/README.md +19 -0
  68. data/tracks/clojure/exercises/wordy/README.md +63 -0
  69. data/tracks/{erlang/exercises/allergies/.meta/readme.go.tmpl → crystal/config/exercise_readme.go.tmpl} +0 -1
  70. data/tracks/crystal/config.json +0 -2
  71. data/tracks/crystal/exercises/acronym/README.md +38 -0
  72. data/tracks/crystal/exercises/anagram/README.md +36 -0
  73. data/tracks/crystal/exercises/atbash-cipher/README.md +57 -0
  74. data/tracks/crystal/exercises/binary/README.md +58 -0
  75. data/tracks/crystal/exercises/binary-search-tree/README.md +83 -0
  76. data/tracks/crystal/exercises/bob/README.md +41 -0
  77. data/tracks/crystal/exercises/bracket-push/README.md +33 -0
  78. data/tracks/crystal/exercises/difference-of-squares/README.md +42 -0
  79. data/tracks/crystal/exercises/flatten-array/README.md +41 -0
  80. data/tracks/crystal/exercises/forth/README.md +52 -0
  81. data/tracks/crystal/exercises/gigasecond/README.md +34 -0
  82. data/tracks/crystal/exercises/hamming/README.md +65 -0
  83. data/tracks/crystal/exercises/hello-world/README.md +78 -0
  84. data/tracks/crystal/exercises/largest-series-product/README.md +43 -0
  85. data/tracks/crystal/exercises/leap/README.md +56 -0
  86. data/tracks/crystal/exercises/pangram/README.md +38 -0
  87. data/tracks/crystal/exercises/pascals-triangle/README.md +44 -0
  88. data/tracks/crystal/exercises/raindrops/README.md +47 -0
  89. data/tracks/crystal/exercises/react/README.md +42 -0
  90. data/tracks/crystal/exercises/rna-transcription/README.md +48 -0
  91. data/tracks/crystal/exercises/roman-numerals/README.md +72 -0
  92. data/tracks/crystal/exercises/run-length-encoding/README.md +53 -0
  93. data/tracks/crystal/exercises/sieve/README.md +57 -0
  94. data/tracks/csharp/config.json +0 -2
  95. data/tracks/delphi/config.json +0 -2
  96. data/tracks/ecmascript/config.json +63 -2
  97. data/tracks/erlang/{exercises/anagram/.meta/readme.go.tmpl → config/exercise_readme.go.tmpl} +0 -1
  98. data/tracks/erlang/config.json +0 -2
  99. data/tracks/erlang/exercises/accumulate/README.md +0 -1
  100. data/tracks/erlang/exercises/all-your-base/README.md +0 -1
  101. data/tracks/erlang/exercises/allergies/README.md +0 -1
  102. data/tracks/erlang/exercises/anagram/README.md +0 -1
  103. data/tracks/erlang/exercises/atbash-cipher/README.md +0 -1
  104. data/tracks/erlang/exercises/bank-account/README.md +0 -1
  105. data/tracks/erlang/exercises/beer-song/README.md +0 -1
  106. data/tracks/erlang/exercises/bob/README.md +0 -1
  107. data/tracks/erlang/exercises/circular-buffer/README.md +0 -1
  108. data/tracks/erlang/exercises/clock/README.md +0 -1
  109. data/tracks/erlang/exercises/collatz-conjecture/README.md +0 -1
  110. data/tracks/erlang/exercises/difference-of-squares/README.md +0 -1
  111. data/tracks/erlang/exercises/etl/README.md +0 -1
  112. data/tracks/erlang/exercises/gigasecond/README.md +0 -1
  113. data/tracks/erlang/exercises/grade-school/README.md +0 -1
  114. data/tracks/erlang/exercises/grains/README.md +0 -1
  115. data/tracks/erlang/exercises/hamming/README.md +0 -1
  116. data/tracks/erlang/exercises/hello-world/README.md +0 -1
  117. data/tracks/erlang/exercises/largest-series-product/README.md +0 -1
  118. data/tracks/erlang/exercises/leap/README.md +0 -1
  119. data/tracks/erlang/exercises/luhn/README.md +0 -1
  120. data/tracks/erlang/exercises/meetup/README.md +0 -1
  121. data/tracks/erlang/exercises/nucleotide-count/README.md +0 -1
  122. data/tracks/erlang/exercises/parallel-letter-frequency/README.md +0 -1
  123. data/tracks/erlang/exercises/phone-number/README.md +0 -1
  124. data/tracks/erlang/exercises/rna-transcription/README.md +0 -1
  125. data/tracks/erlang/exercises/robot-simulator/README.md +0 -1
  126. data/tracks/erlang/exercises/roman-numerals/README.md +0 -1
  127. data/tracks/erlang/exercises/rotational-cipher/README.md +0 -1
  128. data/tracks/erlang/exercises/scrabble-score/README.md +0 -1
  129. data/tracks/erlang/exercises/series/README.md +0 -1
  130. data/tracks/erlang/exercises/space-age/README.md +0 -1
  131. data/tracks/erlang/exercises/spiral-matrix/README.md +0 -1
  132. data/tracks/erlang/exercises/strain/README.md +0 -1
  133. data/tracks/erlang/exercises/sum-of-multiples/README.md +0 -1
  134. data/tracks/erlang/exercises/triangle/README.md +0 -1
  135. data/tracks/erlang/exercises/word-count/README.md +0 -1
  136. data/tracks/erlang/exercises/zipper/README.md +0 -1
  137. data/tracks/factor/config.json +0 -2
  138. data/tracks/fsharp/config.json +0 -2
  139. data/tracks/go/config.json +12 -6
  140. data/tracks/go/exercises/bank-account/bank_account_test.go +60 -1
  141. data/tracks/go/exercises/error-handling/common.go +17 -0
  142. data/tracks/go/exercises/error-handling/error_handling_test.go +37 -4
  143. data/tracks/haskell/config.json +0 -2
  144. data/tracks/java/config.json +10 -2
  145. data/tracks/{erlang/exercises/accumulate → java/exercises/forth}/.meta/readme.go.tmpl +0 -0
  146. data/tracks/java/exercises/forth/README.md +41 -0
  147. data/tracks/java/exercises/forth/build.gradle +18 -0
  148. data/tracks/java/exercises/forth/src/example/java/ForthEvaluator.java +154 -0
  149. data/tracks/java/exercises/forth/src/example/java/Token.java +90 -0
  150. data/tracks/java/exercises/forth/src/main/java/.keep +0 -0
  151. data/tracks/java/exercises/forth/src/test/java/ForthEvaluatorTest.java +355 -0
  152. data/tracks/java/exercises/settings.gradle +1 -0
  153. data/tracks/javascript/config.json +0 -2
  154. data/tracks/kotlin/config.json +30 -2
  155. data/tracks/kotlin/exercises/forth/README.md +32 -0
  156. data/tracks/kotlin/exercises/forth/build.gradle +28 -0
  157. data/tracks/kotlin/exercises/forth/src/example/kotlin/ForthEvaluator.kt +138 -0
  158. data/tracks/kotlin/exercises/forth/src/main/kotlin/.keep +0 -0
  159. data/tracks/kotlin/exercises/forth/src/test/kotlin/ForthEvaluatorTest.kt +352 -0
  160. data/tracks/kotlin/exercises/meetup/README.md +33 -0
  161. data/tracks/kotlin/exercises/meetup/build.gradle +28 -0
  162. data/tracks/kotlin/exercises/meetup/src/example/kotlin/Meetup.kt +45 -0
  163. data/tracks/kotlin/exercises/meetup/src/example/kotlin/MeetupSchedule.kt +1 -0
  164. data/tracks/kotlin/exercises/meetup/src/main/kotlin/MeetupSchedule.kt +5 -0
  165. data/tracks/kotlin/exercises/meetup/src/test/kotlin/MeetupTest.kt +771 -0
  166. data/tracks/kotlin/exercises/say/README.md +72 -0
  167. data/tracks/kotlin/exercises/say/build.gradle +28 -0
  168. data/tracks/kotlin/exercises/say/src/example/kotlin/NumberSpeller.kt +88 -0
  169. data/tracks/kotlin/exercises/say/src/main/kotlin/.keep +0 -0
  170. data/tracks/kotlin/exercises/say/src/test/kotlin/NumberSpellerTest.kt +138 -0
  171. data/tracks/kotlin/exercises/settings.gradle +3 -0
  172. data/tracks/lua/config.json +0 -2
  173. data/tracks/mips/config.json +0 -2
  174. data/tracks/ocaml/config.json +0 -2
  175. data/tracks/perl5/config.json +262 -67
  176. data/tracks/perl6/config.json +98 -26
  177. data/tracks/php/docs/INSTALLATION.md +1 -1
  178. data/tracks/powershell/config.json +0 -2
  179. data/tracks/purescript/config.json +0 -2
  180. data/tracks/python/README.md +2 -2
  181. data/tracks/python/config/exercise_readme.go.tmpl +16 -0
  182. data/tracks/python/config.json +280 -15
  183. data/tracks/python/exercises/accumulate/README.md +46 -0
  184. data/tracks/python/exercises/acronym/README.md +26 -0
  185. data/tracks/python/exercises/all-your-base/README.md +46 -0
  186. data/tracks/python/exercises/allergies/README.md +48 -0
  187. data/tracks/python/exercises/alphametics/README.md +46 -0
  188. data/tracks/python/exercises/anagram/README.md +24 -0
  189. data/tracks/python/exercises/atbash-cipher/README.md +45 -0
  190. data/tracks/python/exercises/beer-song/README.md +338 -0
  191. data/tracks/python/exercises/binary/README.md +46 -0
  192. data/tracks/python/exercises/binary-search/README.md +52 -0
  193. data/tracks/python/exercises/bob/README.md +29 -0
  194. data/tracks/python/exercises/book-store/README.md +85 -0
  195. data/tracks/python/exercises/bracket-push/README.md +21 -0
  196. data/tracks/python/exercises/circular-buffer/README.md +61 -0
  197. data/tracks/python/exercises/clock/README.md +24 -0
  198. data/tracks/python/exercises/crypto-square/README.md +85 -0
  199. data/tracks/python/exercises/diamond/README.md +70 -0
  200. data/tracks/python/exercises/difference-of-squares/README.md +30 -0
  201. data/tracks/python/exercises/etl/README.md +62 -0
  202. data/tracks/python/exercises/flatten-array/README.md +29 -0
  203. data/tracks/python/exercises/gigasecond/README.md +22 -0
  204. data/tracks/python/exercises/grade-school/README.md +53 -0
  205. data/tracks/python/exercises/grains/README.md +45 -0
  206. data/tracks/python/exercises/grep/README.md +82 -0
  207. data/tracks/python/exercises/hamming/README.md +53 -0
  208. data/tracks/python/exercises/hello-world/README.md +32 -0
  209. data/tracks/python/exercises/hexadecimal/README.md +25 -0
  210. data/tracks/python/exercises/house/README.md +124 -0
  211. data/tracks/python/exercises/isogram/README.md +30 -0
  212. data/tracks/python/exercises/kindergarten-garden/README.md +77 -0
  213. data/tracks/python/exercises/largest-series-product/README.md +31 -0
  214. data/tracks/python/exercises/leap/README.md +44 -0
  215. data/tracks/python/exercises/linked-list/README.md +45 -0
  216. data/tracks/python/exercises/list-ops/README.md +21 -0
  217. data/tracks/python/exercises/luhn/README.md +82 -0
  218. data/tracks/python/exercises/matrix/README.md +56 -0
  219. data/tracks/python/exercises/meetup/README.md +41 -0
  220. data/tracks/python/exercises/minesweeper/README.md +41 -0
  221. data/tracks/python/exercises/nth-prime/README.md +26 -0
  222. data/tracks/python/exercises/nucleotide-count/README.md +44 -0
  223. data/tracks/python/exercises/ocr-numbers/README.md +96 -0
  224. data/tracks/python/exercises/octal/README.md +60 -0
  225. data/tracks/python/exercises/palindrome-products/README.md +51 -0
  226. data/tracks/python/exercises/pangram/README.md +26 -0
  227. data/tracks/python/exercises/pascals-triangle/README.md +32 -0
  228. data/tracks/python/exercises/perfect-numbers/README.md +35 -0
  229. data/tracks/python/exercises/phone-number/README.md +45 -0
  230. data/tracks/python/exercises/pig-latin/README.md +35 -0
  231. data/tracks/python/exercises/point-mutations/README.md +52 -0
  232. data/tracks/python/exercises/poker/README.md +23 -0
  233. data/tracks/python/exercises/prime-factors/README.md +47 -0
  234. data/tracks/python/exercises/protein-translation/README.md +60 -0
  235. data/tracks/python/exercises/proverb/README.md +29 -0
  236. data/tracks/python/exercises/pythagorean-triplet/README.md +35 -0
  237. data/tracks/python/exercises/queen-attack/README.md +44 -0
  238. data/tracks/python/exercises/rail-fence-cipher/README.md +71 -0
  239. data/tracks/python/exercises/raindrops/README.md +35 -0
  240. data/tracks/python/exercises/rectangles/README.md +78 -0
  241. data/tracks/python/exercises/rna-transcription/README.md +36 -0
  242. data/tracks/python/exercises/robot-name/README.md +33 -0
  243. data/tracks/python/exercises/robot-simulator/README.md +45 -0
  244. data/tracks/python/exercises/roman-numerals/README.md +60 -0
  245. data/tracks/python/exercises/rotational-cipher/README.md +47 -0
  246. data/tracks/python/exercises/run-length-encoding/README.md +41 -0
  247. data/tracks/python/exercises/saddle-points/README.md +44 -0
  248. data/tracks/python/exercises/say/README.md +80 -0
  249. data/tracks/python/exercises/scale-generator/README.md +71 -0
  250. data/tracks/python/exercises/scrabble-score/README.md +55 -0
  251. data/tracks/python/exercises/secret-handshake/README.md +46 -0
  252. data/tracks/python/exercises/series/README.md +38 -0
  253. data/tracks/python/exercises/sieve/README.md +45 -0
  254. data/tracks/python/exercises/simple-cipher/README.md +101 -0
  255. data/tracks/python/exercises/space-age/README.md +35 -0
  256. data/tracks/python/exercises/strain/README.md +51 -0
  257. data/tracks/python/exercises/sublist/README.md +32 -0
  258. data/tracks/python/exercises/sum-of-multiples/README.md +29 -0
  259. data/tracks/python/exercises/tournament/README.md +79 -0
  260. data/tracks/python/exercises/transpose/README.md +76 -0
  261. data/tracks/python/exercises/triangle/README.md +37 -0
  262. data/tracks/python/exercises/trinary/README.md +39 -0
  263. data/tracks/python/exercises/twelve-days/README.md +46 -0
  264. data/tracks/python/exercises/variable-length-quantity/README.md +50 -0
  265. data/tracks/python/exercises/word-count/README.md +30 -0
  266. data/tracks/python/exercises/word-search/README.md +41 -0
  267. data/tracks/python/exercises/wordy/README.md +74 -0
  268. data/tracks/python/exercises/zebra-puzzle/README.md +43 -0
  269. data/tracks/python/test/check-exercises.py +2 -3
  270. data/tracks/r/config.json +0 -2
  271. data/tracks/ruby/.travis.yml +1 -1
  272. data/tracks/ruby/config/exercise_readme.go.tmpl +16 -0
  273. data/tracks/ruby/config.json +265 -4
  274. data/tracks/ruby/exercises/accumulate/README.md +76 -0
  275. data/tracks/ruby/exercises/acronym/README.md +41 -0
  276. data/tracks/ruby/exercises/all-your-base/README.md +61 -0
  277. data/tracks/ruby/exercises/allergies/README.md +63 -0
  278. data/tracks/ruby/exercises/alphametics/README.md +61 -0
  279. data/tracks/ruby/exercises/anagram/README.md +39 -0
  280. data/tracks/ruby/exercises/atbash-cipher/README.md +60 -0
  281. data/tracks/ruby/exercises/beer-song/README.md +353 -0
  282. data/tracks/ruby/exercises/binary/README.md +61 -0
  283. data/tracks/ruby/exercises/binary-search/README.md +67 -0
  284. data/tracks/ruby/exercises/binary-search-tree/README.md +86 -0
  285. data/tracks/ruby/exercises/bob/README.md +44 -0
  286. data/tracks/ruby/exercises/bowling/README.md +79 -0
  287. data/tracks/ruby/exercises/bracket-push/README.md +36 -0
  288. data/tracks/ruby/exercises/circular-buffer/README.md +76 -0
  289. data/tracks/ruby/exercises/clock/README.md +39 -0
  290. data/tracks/ruby/exercises/collatz-conjecture/README.md +59 -0
  291. data/tracks/ruby/exercises/connect/README.md +60 -0
  292. data/tracks/ruby/exercises/crypto-square/README.md +100 -0
  293. data/tracks/ruby/exercises/custom-set/README.md +37 -0
  294. data/tracks/ruby/exercises/diamond/README.md +85 -0
  295. data/tracks/ruby/exercises/difference-of-squares/README.md +45 -0
  296. data/tracks/ruby/exercises/dominoes/README.md +44 -0
  297. data/tracks/ruby/exercises/etl/README.md +77 -0
  298. data/tracks/ruby/exercises/flatten-array/README.md +44 -0
  299. data/tracks/ruby/exercises/food-chain/README.md +96 -0
  300. data/tracks/ruby/exercises/gigasecond/README.md +37 -0
  301. data/tracks/ruby/exercises/grade-school/README.md +68 -0
  302. data/tracks/ruby/exercises/grains/README.md +60 -0
  303. data/tracks/ruby/exercises/hamming/README.md +68 -0
  304. data/tracks/ruby/exercises/hello-world/README.md +47 -0
  305. data/tracks/ruby/exercises/hexadecimal/README.md +40 -0
  306. data/tracks/ruby/exercises/house/README.md +139 -0
  307. data/tracks/ruby/exercises/isogram/README.md +45 -0
  308. data/tracks/ruby/exercises/kindergarten-garden/README.md +92 -0
  309. data/tracks/ruby/exercises/largest-series-product/README.md +46 -0
  310. data/tracks/ruby/exercises/leap/README.md +59 -0
  311. data/tracks/ruby/exercises/linked-list/README.md +60 -0
  312. data/tracks/ruby/exercises/list-ops/README.md +36 -0
  313. data/tracks/ruby/exercises/luhn/README.md +97 -0
  314. data/tracks/ruby/exercises/matrix/README.md +71 -0
  315. data/tracks/ruby/exercises/meetup/README.md +56 -0
  316. data/tracks/ruby/exercises/minesweeper/README.md +56 -0
  317. data/tracks/ruby/exercises/nth-prime/README.md +41 -0
  318. data/tracks/ruby/exercises/nucleotide-count/README.md +59 -0
  319. data/tracks/ruby/exercises/ocr-numbers/README.md +111 -0
  320. data/tracks/ruby/exercises/octal/README.md +75 -0
  321. data/tracks/ruby/exercises/palindrome-products/README.md +66 -0
  322. data/tracks/ruby/exercises/pangram/README.md +41 -0
  323. data/tracks/ruby/exercises/pascals-triangle/README.md +47 -0
  324. data/tracks/ruby/exercises/perfect-numbers/README.md +50 -0
  325. data/tracks/ruby/exercises/phone-number/README.md +60 -0
  326. data/tracks/ruby/exercises/pig-latin/README.md +50 -0
  327. data/tracks/ruby/exercises/point-mutations/README.md +67 -0
  328. data/tracks/ruby/exercises/poker/README.md +38 -0
  329. data/tracks/ruby/exercises/prime-factors/README.md +62 -0
  330. data/tracks/ruby/exercises/protein-translation/README.md +75 -0
  331. data/tracks/ruby/exercises/proverb/README.md +44 -0
  332. data/tracks/ruby/exercises/pythagorean-triplet/README.md +50 -0
  333. data/tracks/ruby/exercises/queen-attack/README.md +59 -0
  334. data/tracks/ruby/exercises/rail-fence-cipher/README.md +86 -0
  335. data/tracks/ruby/exercises/raindrops/README.md +50 -0
  336. data/tracks/ruby/exercises/rna-transcription/README.md +51 -0
  337. data/tracks/ruby/exercises/robot-name/README.md +57 -0
  338. data/tracks/ruby/exercises/robot-simulator/README.md +60 -0
  339. data/tracks/ruby/exercises/roman-numerals/README.md +75 -0
  340. data/tracks/ruby/exercises/run-length-encoding/README.md +56 -0
  341. data/tracks/ruby/exercises/saddle-points/README.md +59 -0
  342. data/tracks/ruby/exercises/say/README.md +95 -0
  343. data/tracks/ruby/exercises/scale-generator/README.md +86 -0
  344. data/tracks/ruby/exercises/scrabble-score/README.md +70 -0
  345. data/tracks/ruby/exercises/secret-handshake/README.md +61 -0
  346. data/tracks/ruby/exercises/series/README.md +53 -0
  347. data/tracks/ruby/exercises/sieve/README.md +60 -0
  348. data/tracks/ruby/exercises/simple-cipher/README.md +116 -0
  349. data/tracks/ruby/exercises/simple-linked-list/README.md +54 -0
  350. data/tracks/ruby/exercises/space-age/README.md +50 -0
  351. data/tracks/ruby/exercises/strain/README.md +66 -0
  352. data/tracks/ruby/exercises/sum-of-multiples/README.md +44 -0
  353. data/tracks/ruby/exercises/tournament/README.md +94 -0
  354. data/tracks/ruby/exercises/transpose/README.md +91 -0
  355. data/tracks/ruby/exercises/triangle/README.md +52 -0
  356. data/tracks/ruby/exercises/trinary/README.md +54 -0
  357. data/tracks/ruby/exercises/twelve-days/README.md +61 -0
  358. data/tracks/ruby/exercises/two-bucket/README.md +62 -0
  359. data/tracks/ruby/exercises/word-count/README.md +45 -0
  360. data/tracks/ruby/exercises/wordy/README.md +89 -0
  361. data/tracks/rust/README.md +3 -3
  362. data/tracks/rust/_test/WINDOWS_README.md +44 -0
  363. data/tracks/rust/config.json +9 -2
  364. data/tracks/rust/exercises/pig-latin/Cargo-example.toml +8 -0
  365. data/tracks/rust/exercises/pig-latin/Cargo.lock +4 -0
  366. data/tracks/rust/exercises/pig-latin/Cargo.toml +6 -0
  367. data/tracks/rust/exercises/pig-latin/README.md +56 -0
  368. data/tracks/rust/exercises/pig-latin/example.rs +28 -0
  369. data/tracks/rust/exercises/pig-latin/tests/pig-latin.rs +120 -0
  370. data/tracks/rust/problem_ordering.md +2 -2
  371. data/tracks/sml/config.json +0 -2
  372. data/tracks/swift/config/exercise_readme.go.tmpl +16 -0
  373. data/tracks/swift/config.json +304 -79
  374. data/tracks/swift/exercises/accumulate/README.md +43 -0
  375. data/tracks/swift/exercises/acronym/README.md +23 -0
  376. data/tracks/swift/exercises/all-your-base/README.md +43 -0
  377. data/tracks/swift/exercises/allergies/README.md +45 -0
  378. data/tracks/swift/exercises/anagram/README.md +21 -0
  379. data/tracks/swift/exercises/atbash-cipher/README.md +42 -0
  380. data/tracks/swift/exercises/beer-song/README.md +335 -0
  381. data/tracks/swift/exercises/binary/README.md +43 -0
  382. data/tracks/swift/exercises/binary-search/README.md +49 -0
  383. data/tracks/swift/exercises/binary-search-tree/README.md +68 -0
  384. data/tracks/swift/exercises/bob/README.md +26 -0
  385. data/tracks/swift/exercises/bowling/README.md +61 -0
  386. data/tracks/swift/exercises/bracket-push/README.md +18 -0
  387. data/tracks/swift/exercises/clock/README.md +21 -0
  388. data/tracks/swift/exercises/crypto-square/README.md +82 -0
  389. data/tracks/swift/exercises/custom-set/README.md +19 -0
  390. data/tracks/swift/exercises/difference-of-squares/README.md +27 -0
  391. data/tracks/swift/exercises/dominoes/README.md +26 -0
  392. data/tracks/swift/exercises/etl/README.md +59 -0
  393. data/tracks/swift/exercises/flatten-array/README.md +26 -0
  394. data/tracks/swift/exercises/food-chain/README.md +78 -0
  395. data/tracks/swift/exercises/gigasecond/README.md +19 -0
  396. data/tracks/swift/exercises/grade-school/README.md +50 -0
  397. data/tracks/swift/exercises/grains/README.md +42 -0
  398. data/tracks/swift/exercises/hamming/README.md +50 -0
  399. data/tracks/swift/exercises/hello-world/README.md +29 -0
  400. data/tracks/swift/exercises/hexadecimal/README.md +22 -0
  401. data/tracks/swift/exercises/house/README.md +121 -0
  402. data/tracks/swift/exercises/isogram/README.md +27 -0
  403. data/tracks/swift/exercises/kindergarten-garden/README.md +74 -0
  404. data/tracks/swift/exercises/largest-series-product/README.md +28 -0
  405. data/tracks/swift/exercises/leap/README.md +41 -0
  406. data/tracks/swift/exercises/linked-list/README.md +42 -0
  407. data/tracks/swift/exercises/luhn/README.md +79 -0
  408. data/tracks/swift/exercises/matrix/README.md +53 -0
  409. data/tracks/swift/exercises/meetup/README.md +38 -0
  410. data/tracks/swift/exercises/minesweeper/README.md +38 -0
  411. data/tracks/swift/exercises/nth-prime/README.md +23 -0
  412. data/tracks/swift/exercises/nucleotide-count/README.md +41 -0
  413. data/tracks/swift/exercises/ocr-numbers/README.md +93 -0
  414. data/tracks/swift/exercises/octal/README.md +57 -0
  415. data/tracks/swift/exercises/palindrome-products/README.md +48 -0
  416. data/tracks/swift/exercises/pangram/README.md +23 -0
  417. data/tracks/swift/exercises/pascals-triangle/README.md +29 -0
  418. data/tracks/swift/exercises/perfect-numbers/README.md +32 -0
  419. data/tracks/swift/exercises/phone-number/README.md +42 -0
  420. data/tracks/swift/exercises/pig-latin/README.md +32 -0
  421. data/tracks/swift/exercises/poker/README.md +20 -0
  422. data/tracks/swift/exercises/prime-factors/README.md +44 -0
  423. data/tracks/swift/exercises/pythagorean-triplet/README.md +32 -0
  424. data/tracks/swift/exercises/queen-attack/README.md +41 -0
  425. data/tracks/swift/exercises/raindrops/README.md +32 -0
  426. data/tracks/swift/exercises/rna-transcription/README.md +33 -0
  427. data/tracks/swift/exercises/robot-name/README.md +30 -0
  428. data/tracks/swift/exercises/robot-simulator/README.md +42 -0
  429. data/tracks/swift/exercises/roman-numerals/README.md +57 -0
  430. data/tracks/swift/exercises/run-length-encoding/README.md +38 -0
  431. data/tracks/swift/exercises/saddle-points/README.md +41 -0
  432. data/tracks/swift/exercises/scrabble-score/README.md +52 -0
  433. data/tracks/swift/exercises/secret-handshake/README.md +43 -0
  434. data/tracks/swift/exercises/series/README.md +35 -0
  435. data/tracks/swift/exercises/sieve/README.md +42 -0
  436. data/tracks/swift/exercises/simple-cipher/README.md +98 -0
  437. data/tracks/swift/exercises/simple-linked-list/README.md +36 -0
  438. data/tracks/swift/exercises/space-age/README.md +32 -0
  439. data/tracks/swift/exercises/strain/README.md +48 -0
  440. data/tracks/swift/exercises/sublist/README.md +29 -0
  441. data/tracks/swift/exercises/sum-of-multiples/README.md +26 -0
  442. data/tracks/swift/exercises/tournament/README.md +76 -0
  443. data/tracks/swift/exercises/transpose/README.md +73 -0
  444. data/tracks/swift/exercises/triangle/README.md +34 -0
  445. data/tracks/swift/exercises/trinary/README.md +36 -0
  446. data/tracks/swift/exercises/twelve-days/README.md +43 -0
  447. data/tracks/swift/exercises/word-count/README.md +27 -0
  448. data/tracks/swift/exercises/wordy/README.md +71 -0
  449. data/tracks/typescript/README.md +1 -1
  450. data/tracks/typescript/config.json +63 -3
  451. data/tracks/vimscript/config.json +0 -2
  452. metadata +371 -40
  453. data/tracks/erlang/exercises/atbash-cipher/.meta/readme.go.tmpl +0 -17
  454. data/tracks/erlang/exercises/bank-account/.meta/readme.go.tmpl +0 -17
  455. data/tracks/erlang/exercises/beer-song/.meta/readme.go.tmpl +0 -17
  456. data/tracks/erlang/exercises/bob/.meta/readme.go.tmpl +0 -17
  457. data/tracks/erlang/exercises/circular-buffer/.meta/readme.go.tmpl +0 -17
  458. data/tracks/erlang/exercises/clock/.meta/readme.go.tmpl +0 -17
  459. data/tracks/erlang/exercises/collatz-conjecture/.meta/readme.go.tmpl +0 -17
  460. data/tracks/erlang/exercises/difference-of-squares/.meta/readme.go.tmpl +0 -17
  461. data/tracks/erlang/exercises/etl/.meta/readme.go.tmpl +0 -17
  462. data/tracks/erlang/exercises/gigasecond/.meta/readme.go.tmpl +0 -17
  463. data/tracks/erlang/exercises/grade-school/.meta/readme.go.tmpl +0 -17
  464. data/tracks/erlang/exercises/grains/.meta/readme.go.tmpl +0 -17
  465. data/tracks/erlang/exercises/hamming/.meta/readme.go.tmpl +0 -17
  466. data/tracks/erlang/exercises/hello-world/.meta/readme.go.tmpl +0 -17
  467. data/tracks/erlang/exercises/largest-series-product/.meta/readme.go.tmpl +0 -17
  468. data/tracks/erlang/exercises/leap/.meta/readme.go.tmpl +0 -17
  469. data/tracks/erlang/exercises/luhn/.meta/readme.go.tmpl +0 -17
  470. data/tracks/erlang/exercises/meetup/.meta/readme.go.tmpl +0 -17
  471. data/tracks/erlang/exercises/nucleotide-count/.meta/readme.go.tmpl +0 -17
  472. data/tracks/erlang/exercises/parallel-letter-frequency/.meta/readme.go.tmpl +0 -17
  473. data/tracks/erlang/exercises/phone-number/.meta/readme.go.tmpl +0 -17
  474. data/tracks/erlang/exercises/rna-transcription/.meta/readme.go.tmpl +0 -17
  475. data/tracks/erlang/exercises/robot-simulator/.meta/readme.go.tmpl +0 -17
  476. data/tracks/erlang/exercises/roman-numerals/.meta/readme.go.tmpl +0 -17
  477. data/tracks/erlang/exercises/rotational-cipher/.meta/readme.go.tmpl +0 -17
  478. data/tracks/erlang/exercises/scrabble-score/.meta/readme.go.tmpl +0 -17
  479. data/tracks/erlang/exercises/series/.meta/readme.go.tmpl +0 -17
  480. data/tracks/erlang/exercises/space-age/.meta/readme.go.tmpl +0 -17
  481. data/tracks/erlang/exercises/spiral-matrix/.meta/readme.go.tmpl +0 -17
  482. data/tracks/erlang/exercises/strain/.meta/readme.go.tmpl +0 -17
  483. data/tracks/erlang/exercises/sum-of-multiples/.meta/readme.go.tmpl +0 -17
  484. data/tracks/erlang/exercises/triangle/.meta/readme.go.tmpl +0 -17
  485. data/tracks/erlang/exercises/word-count/.meta/readme.go.tmpl +0 -17
  486. data/tracks/erlang/exercises/zipper/.meta/readme.go.tmpl +0 -17
@@ -0,0 +1,355 @@
1
+ import org.junit.Before;
2
+ import org.junit.Ignore;
3
+ import org.junit.Rule;
4
+ import org.junit.Test;
5
+ import org.junit.rules.ExpectedException;
6
+
7
+ import java.util.Arrays;
8
+ import java.util.Collections;
9
+
10
+ import static org.junit.Assert.assertEquals;
11
+
12
+ /*
13
+ * version: 1.2.0
14
+ */
15
+ public class ForthEvaluatorTest {
16
+
17
+ @Rule
18
+ public ExpectedException expectedException = ExpectedException.none();
19
+
20
+ private ForthEvaluator forthEvaluator;
21
+
22
+ @Before
23
+ public void setUp() {
24
+ forthEvaluator = new ForthEvaluator();
25
+ }
26
+
27
+ @Test
28
+ public void testEmptyProgramResultsInEmptyStack() {
29
+ assertEquals(
30
+ Collections.emptyList(),
31
+ forthEvaluator.evaluateProgram(Collections.emptyList()));
32
+ }
33
+
34
+ @Ignore("Remove to run test")
35
+ @Test
36
+ public void testNumbersAreJustPushedOntoTheStack() {
37
+ assertEquals(
38
+ Arrays.asList(1, 2, 3, 4, 5),
39
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 4 5")));
40
+ }
41
+
42
+ @Ignore("Remove to run test")
43
+ @Test
44
+ public void testTwoNumbersCanBeAdded() {
45
+ assertEquals(
46
+ Collections.singletonList(3),
47
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 2 +")));
48
+ }
49
+
50
+ @Ignore("Remove to run test")
51
+ @Test
52
+ public void testErrorIfAdditionAttemptedWithNothingOnTheStack() {
53
+ expectedException.expect(IllegalArgumentException.class);
54
+ expectedException.expectMessage("Addition requires that the stack contain at least 2 values");
55
+
56
+ forthEvaluator.evaluateProgram(Collections.singletonList("+"));
57
+ }
58
+
59
+ @Ignore("Remove to run test")
60
+ @Test
61
+ public void testErrorIfAdditionAttemptedWithOneNumberOnTheStack() {
62
+ expectedException.expect(IllegalArgumentException.class);
63
+ expectedException.expectMessage("Addition requires that the stack contain at least 2 values");
64
+
65
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 +"));
66
+ }
67
+
68
+ @Ignore("Remove to run test")
69
+ @Test
70
+ public void testTwoNumbersCanBeSubtracted() {
71
+ assertEquals(
72
+ Collections.singletonList(-1),
73
+ forthEvaluator.evaluateProgram(Collections.singletonList("3 4 -")));
74
+ }
75
+
76
+ @Ignore("Remove to run test")
77
+ @Test
78
+ public void testErrorIfSubtractionAttemptedWithNothingOnTheStack() {
79
+ expectedException.expect(IllegalArgumentException.class);
80
+ expectedException.expectMessage("Subtraction requires that the stack contain at least 2 values");
81
+
82
+ forthEvaluator.evaluateProgram(Collections.singletonList("-"));
83
+ }
84
+
85
+ @Ignore("Remove to run test")
86
+ @Test
87
+ public void testErrorIfSubtractionAttemptedWithOneNumberOnTheStack() {
88
+ expectedException.expect(IllegalArgumentException.class);
89
+ expectedException.expectMessage("Subtraction requires that the stack contain at least 2 values");
90
+
91
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 -"));
92
+ }
93
+
94
+ @Ignore("Remove to run test")
95
+ @Test
96
+ public void testTwoNumbersCanBeMultiplied() {
97
+ assertEquals(
98
+ Collections.singletonList(8),
99
+ forthEvaluator.evaluateProgram(Collections.singletonList("2 4 *")));
100
+ }
101
+
102
+ @Ignore("Remove to run test")
103
+ @Test
104
+ public void testErrorIfMultiplicationAttemptedWithNothingOnTheStack() {
105
+ expectedException.expect(IllegalArgumentException.class);
106
+ expectedException.expectMessage("Multiplication requires that the stack contain at least 2 values");
107
+
108
+ forthEvaluator.evaluateProgram(Collections.singletonList("*"));
109
+ }
110
+
111
+ @Ignore("Remove to run test")
112
+ @Test
113
+ public void testErrorIfMultiplicationAttemptedWithOneNumberOnTheStack() {
114
+ expectedException.expect(IllegalArgumentException.class);
115
+ expectedException.expectMessage("Multiplication requires that the stack contain at least 2 values");
116
+
117
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 *"));
118
+ }
119
+
120
+ @Ignore("Remove to run test")
121
+ @Test
122
+ public void testTwoNumbersCanBeDivided() {
123
+ assertEquals(
124
+ Collections.singletonList(4),
125
+ forthEvaluator.evaluateProgram(Collections.singletonList("12 3 /")));
126
+ }
127
+
128
+ @Ignore("Remove to run test")
129
+ @Test
130
+ public void testThatIntegerDivisionIsUsed() {
131
+ assertEquals(
132
+ Collections.singletonList(2),
133
+ forthEvaluator.evaluateProgram(Collections.singletonList("8 3 /")));
134
+ }
135
+
136
+ @Ignore("Remove to run test")
137
+ @Test
138
+ public void testErrorIfDividingByZero() {
139
+ expectedException.expect(IllegalArgumentException.class);
140
+ expectedException.expectMessage("Division by 0 is not allowed");
141
+
142
+ forthEvaluator.evaluateProgram(Collections.singletonList("4 0 /"));
143
+ }
144
+
145
+ @Ignore("Remove to run test")
146
+ @Test
147
+ public void testErrorIfDivisionAttemptedWithNothingOnTheStack() {
148
+ expectedException.expect(IllegalArgumentException.class);
149
+ expectedException.expectMessage("Division requires that the stack contain at least 2 values");
150
+
151
+ forthEvaluator.evaluateProgram(Collections.singletonList("/"));
152
+ }
153
+
154
+ @Ignore("Remove to run test")
155
+ @Test
156
+ public void testErrorIfDivisionAttemptedWithOneNumberOnTheStack() {
157
+ expectedException.expect(IllegalArgumentException.class);
158
+ expectedException.expectMessage("Division requires that the stack contain at least 2 values");
159
+
160
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 /"));
161
+ }
162
+
163
+ @Ignore("Remove to run test")
164
+ @Test
165
+ public void testCombinedAdditionAndSubtraction() {
166
+ assertEquals(
167
+ Collections.singletonList(-1),
168
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 2 + 4 -")));
169
+ }
170
+
171
+ @Ignore("Remove to run test")
172
+ @Test
173
+ public void testCombinedMultiplicationAndDivision() {
174
+ assertEquals(
175
+ Collections.singletonList(2),
176
+ forthEvaluator.evaluateProgram(Collections.singletonList("2 4 * 3 /")));
177
+ }
178
+
179
+ @Ignore("Remove to run test")
180
+ @Test
181
+ public void testDupCopiesTheTopValueOnTheStack() {
182
+ assertEquals(
183
+ Arrays.asList(1, 1),
184
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 DUP")));
185
+ }
186
+
187
+ @Ignore("Remove to run test")
188
+ @Test
189
+ public void testDupParsingIsCaseInsensitive() {
190
+ assertEquals(
191
+ Arrays.asList(1, 2, 2),
192
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 2 Dup")));
193
+ }
194
+
195
+ @Ignore("Remove to run test")
196
+ @Test
197
+ public void testErrorIfDuplicatingAttemptedWithNothingOnTheStack() {
198
+ expectedException.expect(IllegalArgumentException.class);
199
+ expectedException.expectMessage("Duplicating requires that the stack contain at least 1 value");
200
+
201
+ forthEvaluator.evaluateProgram(Collections.singletonList("dup"));
202
+ }
203
+
204
+ @Ignore("Remove to run test")
205
+ @Test
206
+ public void testDropRemovesTheTopValueOnTheStackIfItIsTheOnlyOne() {
207
+ assertEquals(
208
+ Collections.emptyList(),
209
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 drop")));
210
+ }
211
+
212
+ @Ignore("Remove to run test")
213
+ @Test
214
+ public void testDropRemovesTheTopValueOnTheStackIfItIsNotTheOnlyOne() {
215
+ assertEquals(
216
+ Collections.singletonList(1),
217
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 2 drop")));
218
+ }
219
+
220
+ @Ignore("Remove to run test")
221
+ @Test
222
+ public void testErrorIfDroppingAttemptedWithNothingOnTheStack() {
223
+ expectedException.expect(IllegalArgumentException.class);
224
+ expectedException.expectMessage("Dropping requires that the stack contain at least 1 value");
225
+
226
+ forthEvaluator.evaluateProgram(Collections.singletonList("drop"));
227
+ }
228
+
229
+ @Ignore("Remove to run test")
230
+ @Test
231
+ public void testSwapSwapsTheTopTwosValueOnTheStackIfTheyAreTheOnlyOnes() {
232
+ assertEquals(
233
+ Arrays.asList(2, 1),
234
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 2 swap")));
235
+ }
236
+
237
+ @Ignore("Remove to run test")
238
+ @Test
239
+ public void testSwapSwapsTheTopTwosValueOnTheStackIfTheyAreNotTheOnlyOnes() {
240
+ assertEquals(
241
+ Arrays.asList(1, 3, 2),
242
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 swap")));
243
+ }
244
+
245
+ @Ignore("Remove to run test")
246
+ @Test
247
+ public void testErrorIfSwappingAttemptedWithNothingOnTheStack() {
248
+ expectedException.expect(IllegalArgumentException.class);
249
+ expectedException.expectMessage("Swapping requires that the stack contain at least 2 values");
250
+
251
+ forthEvaluator.evaluateProgram(Collections.singletonList("swap"));
252
+ }
253
+
254
+ @Ignore("Remove to run test")
255
+ @Test
256
+ public void testErrorIfSwappingAttemptedWithOneNumberOnTheStack() {
257
+ expectedException.expect(IllegalArgumentException.class);
258
+ expectedException.expectMessage("Swapping requires that the stack contain at least 2 values");
259
+
260
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 swap"));
261
+ }
262
+
263
+ @Ignore("Remove to run test")
264
+ @Test
265
+ public void testOverCopiesTheSecondElementIfThereAreOnlyTwo() {
266
+ assertEquals(
267
+ Arrays.asList(1, 2, 1),
268
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 2 over")));
269
+ }
270
+
271
+ @Ignore("Remove to run test")
272
+ @Test
273
+ public void testOverCopiesTheSecondElementIfThereAreMoreThanTwo() {
274
+ assertEquals(
275
+ Arrays.asList(1, 2, 3, 2),
276
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 over")));
277
+ }
278
+
279
+ @Ignore("Remove to run test")
280
+ @Test
281
+ public void testErrorIfOveringAttemptedWithNothingOnTheStack() {
282
+ expectedException.expect(IllegalArgumentException.class);
283
+ expectedException.expectMessage("Overing requires that the stack contain at least 2 values");
284
+
285
+ forthEvaluator.evaluateProgram(Collections.singletonList("over"));
286
+ }
287
+
288
+ @Ignore("Remove to run test")
289
+ @Test
290
+ public void testErrorIfOveringAttemptedWithOneNumberOnTheStack() {
291
+ expectedException.expect(IllegalArgumentException.class);
292
+ expectedException.expectMessage("Overing requires that the stack contain at least 2 values");
293
+
294
+ forthEvaluator.evaluateProgram(Collections.singletonList("1 over"));
295
+ }
296
+
297
+ @Ignore("Remove to run test")
298
+ @Test
299
+ public void testUserDefinedOperatorsCanConsistOfBuiltInOperators() {
300
+ assertEquals(
301
+ Arrays.asList(1, 1, 1),
302
+ forthEvaluator.evaluateProgram(Arrays.asList(": dup-twice dup dup ;", "1 dup-twice")));
303
+ }
304
+
305
+ @Ignore("Remove to run test")
306
+ @Test
307
+ public void testUserDefinedOperatorsAreEvaluatedInTheCorrectOrder() {
308
+ assertEquals(
309
+ Arrays.asList(1, 2, 3),
310
+ forthEvaluator.evaluateProgram(Arrays.asList(": countup 1 2 3 ;", "countup")));
311
+ }
312
+
313
+ @Ignore("Remove to run test")
314
+ @Test
315
+ public void testCanRedefineAUserDefinedOperator() {
316
+ assertEquals(
317
+ Arrays.asList(1, 1, 1),
318
+ forthEvaluator.evaluateProgram(Arrays.asList(": foo dup ;", ": foo dup dup ;", "1 foo")));
319
+ }
320
+
321
+ @Ignore("Remove to run test")
322
+ @Test
323
+ public void testCanOverrideBuiltInWordOperators() {
324
+ assertEquals(
325
+ Arrays.asList(1, 1),
326
+ forthEvaluator.evaluateProgram(Arrays.asList(": swap dup ;", "1 swap")));
327
+ }
328
+
329
+ @Ignore("Remove to run test")
330
+ @Test
331
+ public void testCanOverrideBuiltInArithmeticOperators() {
332
+ assertEquals(
333
+ Collections.singletonList(12),
334
+ forthEvaluator.evaluateProgram(Arrays.asList(": + * ;", "3 4 +")));
335
+ }
336
+
337
+ @Ignore("Remove to run test")
338
+ @Test
339
+ public void testCannotRedefineNumbers() {
340
+ expectedException.expect(IllegalArgumentException.class);
341
+ expectedException.expectMessage("Cannot redefine numbers");
342
+
343
+ forthEvaluator.evaluateProgram(Collections.singletonList(": 1 2 ;"));
344
+ }
345
+
346
+ @Ignore("Remove to run test")
347
+ @Test
348
+ public void testErrorIfEvaluatingAnUndefinedOperator() {
349
+ expectedException.expect(IllegalArgumentException.class);
350
+ expectedException.expectMessage("No definition available for operator \"foo\"");
351
+
352
+ forthEvaluator.evaluateProgram(Collections.singletonList("foo"));
353
+ }
354
+
355
+ }
@@ -25,6 +25,7 @@ include 'difference-of-squares'
25
25
  include 'etl'
26
26
  include 'flatten-array'
27
27
  include 'food-chain'
28
+ include 'forth'
28
29
  include 'gigasecond'
29
30
  include 'grade-school'
30
31
  include 'hamming'
@@ -1,7 +1,5 @@
1
1
  {
2
- "slug": "javascript",
3
2
  "language": "JavaScript",
4
- "repository": "https://github.com/exercism/javascript",
5
3
  "active": true,
6
4
  "test_pattern": ".*[.]spec[.]js$",
7
5
  "exercises": [
@@ -1,7 +1,5 @@
1
1
  {
2
- "slug": "kotlin",
3
2
  "language": "Kotlin",
4
- "repository": "https://github.com/exercism/kotlin",
5
3
  "active": true,
6
4
  "foregone": [
7
5
 
@@ -479,6 +477,16 @@
479
477
 
480
478
  ]
481
479
  },
480
+ {
481
+ "uuid": "5607dae5-13aa-4cd4-8b4c-d270516182d7",
482
+ "slug": "say",
483
+ "core": false,
484
+ "unlocked_by": null,
485
+ "difficulty": 6,
486
+ "topics": [
487
+
488
+ ]
489
+ },
482
490
  {
483
491
  "uuid": "f754e1cc-cb88-4776-ab11-3e6ae8362d5a",
484
492
  "slug": "anagram",
@@ -499,6 +507,16 @@
499
507
 
500
508
  ]
501
509
  },
510
+ {
511
+ "uuid": "d617987e-64b8-4c21-89a9-66a932c4668d",
512
+ "slug": "meetup",
513
+ "core": false,
514
+ "unlocked_by": null,
515
+ "difficulty": 7,
516
+ "topics": [
517
+
518
+ ]
519
+ },
502
520
  {
503
521
  "uuid": "1dcefdea-5447-4622-a064-079aad781398",
504
522
  "slug": "clock",
@@ -539,6 +557,16 @@
539
557
 
540
558
  ]
541
559
  },
560
+ {
561
+ "uuid": "eecd4f8b-eedc-49a3-adad-49747521ef66",
562
+ "slug": "forth",
563
+ "core": false,
564
+ "unlocked_by": null,
565
+ "difficulty": 9,
566
+ "topics": [
567
+
568
+ ]
569
+ },
542
570
  {
543
571
  "uuid": "240788cd-afa5-4fd6-8df0-a158239c0610",
544
572
  "slug": "react",
@@ -0,0 +1,32 @@
1
+ # Forth
2
+
3
+ Implement an evaluator for a very simple subset of Forth.
4
+
5
+ [Forth](https://en.wikipedia.org/wiki/Forth_%28programming_language%29)
6
+ is a stack-based programming language. Implement a very basic evaluator
7
+ for a small subset of Forth.
8
+
9
+ Your evaluator has to support the following words:
10
+
11
+ - `+`, `-`, `*`, `/` (integer arithmetic)
12
+ - `DUP`, `DROP`, `SWAP`, `OVER` (stack manipulation)
13
+
14
+ Your evaluator also has to support defining new words using the
15
+ customary syntax: `: word-name definition ;`.
16
+
17
+ To keep things simple the only data type you need to support is signed
18
+ integers of at least 16 bits size.
19
+
20
+ You should use the following rules for the syntax: a number is a
21
+ sequence of one or more (ASCII) digits, a word is a sequence of one or
22
+ more letters, digits, symbols or punctuation that is not a number.
23
+ (Forth probably uses slightly different rules, but this is close
24
+ enough.)
25
+
26
+ Words are case-insensitive.
27
+
28
+
29
+
30
+
31
+ ## Submitting Incomplete Solutions
32
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,28 @@
1
+ buildscript {
2
+ ext.kotlin_version = '1.1.1'
3
+ repositories {
4
+ mavenCentral()
5
+ }
6
+ dependencies {
7
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
8
+ }
9
+ }
10
+
11
+ apply plugin: 'kotlin'
12
+
13
+ repositories {
14
+ mavenCentral()
15
+ }
16
+
17
+ dependencies {
18
+ compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
19
+
20
+ testCompile 'junit:junit:4.12'
21
+ testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
22
+ }
23
+ test {
24
+ testLogging {
25
+ exceptionFormat = 'full'
26
+ events = ["passed", "failed", "skipped"]
27
+ }
28
+ }
@@ -0,0 +1,138 @@
1
+ import java.util.*
2
+
3
+ sealed class Token {
4
+
5
+ data class OpDefToken(val newOp: String, val newOpDefTokens: List<Token>): Token() {
6
+
7
+ companion object {
8
+ fun fromString(string: String): OpDefToken {
9
+ val trimmedLine = string.substring(2..string.lastIndex - 2)
10
+ val newOpEnd = trimmedLine.indexOf(" ")
11
+
12
+ require(newOpEnd >= 0) { "Incomplete operation definition" }
13
+
14
+ val newOpToken = Token.fromString(trimmedLine.substring(0 until newOpEnd)).first()
15
+
16
+ require(newOpToken is OpToken) { "Cannot redefine numbers" }
17
+
18
+ val newOpDefTokens = Token.fromString(trimmedLine.substring(newOpEnd + 1))
19
+ return OpDefToken((newOpToken as OpToken).op, newOpDefTokens)
20
+ }
21
+ }
22
+
23
+ }
24
+
25
+ data class OpToken(val op: String): Token()
26
+ data class IntToken(val rawValue: Int): Token()
27
+
28
+ companion object {
29
+ val opChars = "A-z+/*\\-"
30
+
31
+ fun fromString(string: String): List<Token> {
32
+ return when {
33
+ string.startsWith(':') -> listOf(OpDefToken.fromString(string))
34
+ string.matches(Regex("[$opChars]+(?:-[$opChars]+)*")) -> listOf(OpToken(string.toLowerCase()))
35
+ string.matches(Regex("\\d+")) -> listOf(IntToken(string.toInt()))
36
+ else -> string.split(delimiters = " ").flatMap { Token.fromString(it) }
37
+ }
38
+ }
39
+ }
40
+
41
+ }
42
+
43
+ class ForthEvaluator {
44
+
45
+ companion object {
46
+ private val builtInOps = mapOf<String, (Deque<Int>) -> Any>(
47
+ Pair("+") { values ->
48
+ require(values.size >= 2) { "Addition requires that the stack contain at least 2 values" }
49
+ values.push(values.pop() + values.pop())
50
+ },
51
+
52
+ Pair("-") { values ->
53
+ require(values.size >= 2) { "Subtraction requires that the stack contain at least 2 values" }
54
+ val topValue = values.pop()
55
+ val secondValue = values.pop()
56
+ values.push(secondValue - topValue)
57
+ },
58
+
59
+ Pair("*") { values ->
60
+ require(values.size >= 2) { "Multiplication requires that the stack contain at least 2 values" }
61
+ values.push(values.pop() * values.pop())
62
+ },
63
+
64
+ Pair("/") { values ->
65
+ require(values.size >= 2) { "Division requires that the stack contain at least 2 values" }
66
+ val topValue = values.pop()
67
+ val secondValue = values.pop()
68
+ require(topValue != 0) { "Division by 0 is not allowed" }
69
+ values.push(secondValue / topValue)
70
+ },
71
+
72
+ Pair("dup") { values ->
73
+ require(values.isNotEmpty()) { "Duplicating requires that the stack contain at least 1 value" }
74
+ values.push(values.peek())
75
+ },
76
+
77
+ Pair("drop") { values ->
78
+ require(values.isNotEmpty()) { "Dropping requires that the stack contain at least 1 value" }
79
+ values.pop()
80
+ },
81
+
82
+ Pair("swap") { values ->
83
+ require(values.size >= 2) { "Swapping requires that the stack contain at least 2 values" }
84
+ val topValue = values.pop()
85
+ val secondValue = values.pop()
86
+ values.push(topValue)
87
+ values.push(secondValue)
88
+ },
89
+
90
+ Pair("over") { values ->
91
+ require(values.size >= 2) { "Overing requires that the stack contain at least 2 values" }
92
+ val topValue = values.pop()
93
+ val secondValue = values.peek()
94
+ values.push(topValue)
95
+ values.push(secondValue)
96
+ }
97
+ )
98
+ }
99
+
100
+ private val values = ArrayDeque<Int>()
101
+
102
+ private val tokens = mutableListOf<Token>()
103
+
104
+ private val userOps = mutableMapOf<String, List<Token>>()
105
+
106
+ fun evaluateProgram(program: List<String>): List<Int> {
107
+ parse(program)
108
+ evaluate()
109
+ return values.toList().asReversed()
110
+ }
111
+
112
+ private fun parse(program: List<String>) = tokens.addAll(program.flatMap(Token.Companion::fromString))
113
+
114
+ private fun evaluate() {
115
+ while (tokens.isNotEmpty()) {
116
+ val token = tokens.removeAt(0)
117
+
118
+ when (token) {
119
+ is Token.OpDefToken -> userOps.put(token.newOp.toLowerCase(), token.newOpDefTokens)
120
+ is Token.OpToken -> evaluateOpToken(token)
121
+ is Token.IntToken -> values.push(token.rawValue)
122
+ }
123
+ }
124
+ }
125
+
126
+ private fun evaluateOpToken(opToken: Token.OpToken) {
127
+ val op = opToken.op
128
+
129
+ if (userOps.containsKey(op)) {
130
+ userOps[op]!!.asReversed().forEach { token -> tokens.add(index = 0, element = token) }
131
+ } else if (builtInOps.containsKey(op)) {
132
+ builtInOps[op]!!.invoke(values)
133
+ } else {
134
+ throw IllegalArgumentException("No definition available for operator \"$op\"")
135
+ }
136
+ }
137
+
138
+ }