trackler 2.2.1.45 → 2.2.1.46

Sign up to get free protection for your applications and to get access to all the features.
Files changed (508) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/complex-numbers/description.md +27 -0
  4. data/problem-specifications/exercises/crypto-square/canonical-data.json +39 -43
  5. data/problem-specifications/exercises/crypto-square/description.md +6 -4
  6. data/problem-specifications/exercises/hamming/canonical-data.json +5 -5
  7. data/problem-specifications/exercises/kindergarten-garden/description.md +10 -10
  8. data/problem-specifications/exercises/leap/canonical-data.json +2 -2
  9. data/problem-specifications/exercises/markdown/canonical-data.json +2 -2
  10. data/problem-specifications/exercises/nucleotide-count/canonical-data.json +12 -1
  11. data/problem-specifications/exercises/pangram/canonical-data.json +7 -1
  12. data/problem-specifications/exercises/queen-attack/canonical-data.json +83 -26
  13. data/problem-specifications/exercises/space-age/description.md +1 -2
  14. data/problem-specifications/exercises/zipper/canonical-data.json +671 -0
  15. data/tracks/bash/config.json +13 -1
  16. data/tracks/bash/exercises/atbash-cipher/README.md +45 -0
  17. data/tracks/bash/exercises/atbash-cipher/atbash_cipher_tests.sh +73 -0
  18. data/tracks/bash/exercises/atbash-cipher/example.sh +14 -0
  19. data/tracks/bash/exercises/gigasecond/.meta/hints.md +33 -0
  20. data/tracks/bash/exercises/two-fer/README.md +0 -22
  21. data/tracks/c/exercises/allergies/src/allergies.h +9 -9
  22. data/tracks/c/exercises/allergies/src/example.c +2 -2
  23. data/tracks/c/exercises/allergies/src/example.h +9 -9
  24. data/tracks/c/exercises/allergies/test/test_allergies.c +34 -34
  25. data/tracks/c/exercises/clock/test/test_clock.c +0 -52
  26. data/tracks/c/exercises/meetup/test/test_meetup.c +604 -114
  27. data/tracks/c/exercises/nucleotide-count/src/example.c +10 -10
  28. data/tracks/c/exercises/palindrome-products/src/example.c +8 -8
  29. data/tracks/c/exercises/palindrome-products/src/example.h +5 -5
  30. data/tracks/c/exercises/palindrome-products/test/test_palindrome_products.c +8 -6
  31. data/tracks/c/exercises/robot-simulator/src/example.c +19 -19
  32. data/tracks/c/exercises/robot-simulator/src/robot_simulator.h +24 -24
  33. data/tracks/c/exercises/robot-simulator/test/test_robot_simulator.c +35 -34
  34. data/tracks/c/exercises/series/src/example.c +10 -10
  35. data/tracks/c/exercises/series/src/series.h +5 -5
  36. data/tracks/c/exercises/series/test/test_series.c +77 -30
  37. data/tracks/c/exercises/sieve/src/example.c +17 -17
  38. data/tracks/c/exercises/sieve/src/sieve.h +2 -2
  39. data/tracks/c/exercises/sieve/test/test_sieve.c +6 -6
  40. data/tracks/c/exercises/space-age/src/example.c +1 -1
  41. data/tracks/c/exercises/space-age/src/example.h +3 -3
  42. data/tracks/c/exercises/space-age/test/test_space_age.c +2 -0
  43. data/tracks/c/exercises/sum-of-multiples/src/example.c +3 -1
  44. data/tracks/c/exercises/sum-of-multiples/test/test_sum_of_multiples.c +17 -0
  45. data/tracks/c/exercises/triangle/src/example.c +4 -4
  46. data/tracks/c/exercises/triangle/src/example.h +4 -4
  47. data/tracks/c/exercises/triangle/src/triangle.h +1 -1
  48. data/tracks/c/exercises/triangle/test/test_triangle.c +18 -16
  49. data/tracks/c/exercises/word-count/src/example.c +24 -24
  50. data/tracks/c/exercises/word-count/src/word_count.h +3 -3
  51. data/tracks/c/exercises/word-count/test/test_word_count.c +139 -139
  52. data/tracks/cfml/exercises/acronym/README.md +31 -0
  53. data/tracks/cfml/exercises/atbash-cipher/README.md +50 -0
  54. data/tracks/cfml/exercises/bob/README.md +34 -0
  55. data/tracks/cfml/exercises/diamond/README.md +75 -0
  56. data/tracks/cfml/exercises/difference-of-squares/README.md +35 -0
  57. data/tracks/cfml/exercises/flatten-array/README.md +34 -0
  58. data/tracks/cfml/exercises/gigasecond/README.md +27 -0
  59. data/tracks/cfml/exercises/grains/README.md +50 -0
  60. data/tracks/cfml/exercises/hamming/README.md +58 -0
  61. data/tracks/cfml/exercises/hello-world/README.md +37 -0
  62. data/tracks/cfml/exercises/isogram/README.md +35 -0
  63. data/tracks/cfml/exercises/largest-series-product/README.md +36 -0
  64. data/tracks/cfml/exercises/leap/README.md +16 -0
  65. data/tracks/cfml/exercises/luhn/README.md +87 -0
  66. data/tracks/cfml/exercises/markdown/README.md +34 -0
  67. data/tracks/cfml/exercises/nth-prime/README.md +31 -0
  68. data/tracks/cfml/exercises/pangram/README.md +31 -0
  69. data/tracks/cfml/exercises/pig-latin/README.md +40 -0
  70. data/tracks/cfml/exercises/raindrops/README.md +40 -0
  71. data/tracks/cfml/exercises/rna-transcription/README.md +41 -0
  72. data/tracks/cfml/exercises/saddle-points/README.md +49 -0
  73. data/tracks/cfml/exercises/scrabble-score/README.md +60 -0
  74. data/tracks/cfml/exercises/secret-handshake/README.md +51 -0
  75. data/tracks/cfml/exercises/space-age/README.md +41 -0
  76. data/tracks/cfml/exercises/sum-of-multiples/README.md +34 -0
  77. data/tracks/cfml/exercises/triangle/README.md +42 -0
  78. data/tracks/cfml/exercises/word-count/README.md +35 -0
  79. data/tracks/clojure/config.json +10 -0
  80. data/tracks/clojure/exercises/spiral-matrix/README.md +32 -0
  81. data/tracks/clojure/exercises/spiral-matrix/project.clj +4 -0
  82. data/tracks/clojure/exercises/spiral-matrix/src/example.clj +11 -0
  83. data/tracks/clojure/exercises/spiral-matrix/src/spiral_matrix.clj +3 -0
  84. data/tracks/clojure/exercises/spiral-matrix/test/spiral_matrix_test.clj +58 -0
  85. data/tracks/common-lisp/config.json +20 -0
  86. data/tracks/common-lisp/exercises/hello-world/README.md +68 -0
  87. data/tracks/common-lisp/exercises/hello-world/example.lisp +9 -0
  88. data/tracks/common-lisp/exercises/hello-world/hello-world-test.lisp +21 -0
  89. data/tracks/common-lisp/exercises/hello-world/hello-world.lisp +6 -0
  90. data/tracks/common-lisp/exercises/perfect-numbers/README.md +72 -0
  91. data/tracks/common-lisp/exercises/perfect-numbers/example.lisp +17 -0
  92. data/tracks/common-lisp/exercises/perfect-numbers/perfect-numbers-test.lisp +56 -0
  93. data/tracks/common-lisp/exercises/perfect-numbers/perfect-numbers.lisp +7 -0
  94. data/tracks/cpp/.travis.yml +34 -14
  95. data/tracks/cpp/docs/INSTALLATION.md +17 -28
  96. data/tracks/cpp/docs/TESTS.md +13 -21
  97. data/tracks/crystal/config.json +10 -0
  98. data/tracks/crystal/exercises/triangle/spec/triangle_spec.cr +60 -0
  99. data/tracks/crystal/exercises/triangle/src/example.cr +31 -0
  100. data/tracks/crystal/exercises/triangle/src/triangle.cr +1 -0
  101. data/tracks/crystal/generator/spec/remote_data_file_spec.cr +0 -1
  102. data/tracks/crystal/generator/src/generators/triangle.cr +38 -0
  103. data/tracks/crystal/generator/src/remote_data_file.cr +1 -1
  104. data/tracks/csharp/exercises/difference-of-squares/DifferenceOfSquares.cs +4 -4
  105. data/tracks/csharp/exercises/difference-of-squares/DifferenceOfSquaresTest.cs +22 -27
  106. data/tracks/csharp/exercises/difference-of-squares/Example.cs +5 -5
  107. data/tracks/csharp/exercises/error-handling/ErrorHandlingTest.cs +4 -4
  108. data/tracks/csharp/exercises/flatten-array/Example.cs +1 -1
  109. data/tracks/csharp/exercises/flatten-array/FlattenArray.cs +1 -1
  110. data/tracks/csharp/exercises/flatten-array/FlattenArrayTest.cs +106 -72
  111. data/tracks/csharp/exercises/largest-series-product/LargestSeriesProductTest.cs +24 -98
  112. data/tracks/csharp/exercises/minesweeper/Example.cs +3 -3
  113. data/tracks/csharp/exercises/minesweeper/Minesweeper.cs +1 -1
  114. data/tracks/csharp/exercises/minesweeper/MinesweeperTest.cs +155 -57
  115. data/tracks/csharp/generators/Exercises/DifferenceOfSquares.cs +25 -0
  116. data/tracks/csharp/generators/Exercises/FlattenArray.cs +36 -0
  117. data/tracks/csharp/generators/Exercises/LargestSeriesProduct.cs +18 -0
  118. data/tracks/csharp/generators/Exercises/Minesweeper.cs +32 -0
  119. data/tracks/d/docs/EXERCISE_README_INSERT.md +1 -1
  120. data/tracks/d/exercises/bob/README.md +1 -1
  121. data/tracks/d/exercises/circular-buffer/README.md +1 -1
  122. data/tracks/d/exercises/crypto-square/README.md +1 -1
  123. data/tracks/d/exercises/difference-of-squares/README.md +1 -1
  124. data/tracks/d/exercises/etl/README.md +1 -1
  125. data/tracks/d/exercises/gigasecond/README.md +1 -1
  126. data/tracks/d/exercises/hamming/README.md +1 -1
  127. data/tracks/d/exercises/hello-world/README.md +1 -1
  128. data/tracks/d/exercises/leap/README.md +1 -1
  129. data/tracks/d/exercises/nucleotide-count/README.md +1 -1
  130. data/tracks/d/exercises/pangram/README.md +1 -1
  131. data/tracks/d/exercises/raindrops/README.md +1 -1
  132. data/tracks/d/exercises/react/README.md +1 -1
  133. data/tracks/d/exercises/rna-transcription/README.md +1 -1
  134. data/tracks/d/exercises/robot-name/README.md +1 -1
  135. data/tracks/d/exercises/roman-numerals/README.md +1 -1
  136. data/tracks/d/exercises/series/README.md +1 -1
  137. data/tracks/d/exercises/triangle/README.md +1 -1
  138. data/tracks/dart/CONTRIBUTING.md +61 -0
  139. data/tracks/dart/README.md +10 -47
  140. data/tracks/dart/config.json +13 -1
  141. data/tracks/dart/exercises/anagram/README.md +10 -0
  142. data/tracks/dart/exercises/bob/README.md +11 -0
  143. data/tracks/dart/exercises/difference-of-squares/README.md +11 -0
  144. data/tracks/dart/exercises/gigasecond/README.md +11 -0
  145. data/tracks/dart/exercises/gigasecond/test/gigasecond_test.dart +56 -33
  146. data/tracks/dart/exercises/hamming/README.md +11 -0
  147. data/tracks/dart/exercises/hamming/lib/example.dart +2 -2
  148. data/tracks/dart/exercises/hamming/test/hamming_test.dart +41 -24
  149. data/tracks/dart/exercises/hello-world/README.md +11 -0
  150. data/tracks/dart/exercises/leap/README.md +12 -1
  151. data/tracks/dart/exercises/phone-number/README.md +56 -0
  152. data/tracks/dart/exercises/phone-number/lib/example.dart +45 -0
  153. data/tracks/dart/exercises/phone-number/lib/phone_number.dart +3 -0
  154. data/tracks/dart/exercises/phone-number/pubspec.lock +293 -0
  155. data/tracks/dart/exercises/phone-number/pubspec.yaml +3 -0
  156. data/tracks/dart/exercises/phone-number/test/phone_number_test.dart +66 -0
  157. data/tracks/dart/exercises/raindrops/README.md +35 -0
  158. data/tracks/dart/exercises/rna-transcription/README.md +11 -0
  159. data/tracks/dart/exercises/word-count/README.md +14 -3
  160. data/tracks/delphi/docs/RESOURCES.md +10 -11
  161. data/tracks/elixir/exercises/hello-world/hello_world.exs +1 -1
  162. data/tracks/elixir/exercises/secret-handshake/README.md +3 -5
  163. data/tracks/elm/exercises/isogram/Isogram.example.elm +4 -4
  164. data/tracks/erlang/config.json +10 -0
  165. data/tracks/erlang/exercises/sieve/README.md +88 -0
  166. data/tracks/erlang/exercises/sieve/include/exercism.hrl +11 -0
  167. data/tracks/erlang/exercises/sieve/rebar.config +30 -0
  168. data/tracks/erlang/exercises/sieve/src/example.erl +16 -0
  169. data/tracks/erlang/exercises/sieve/src/sieve.app.src +9 -0
  170. data/tracks/erlang/exercises/sieve/src/sieve.erl +8 -0
  171. data/tracks/erlang/exercises/sieve/test/sieve_tests.erl +38 -0
  172. data/tracks/fsharp/.gitignore +2 -1
  173. data/tracks/fsharp/exercises/crypto-square/CryptoSquareTest.fs +10 -6
  174. data/tracks/fsharp/exercises/leap/LeapTest.fs +2 -2
  175. data/tracks/fsharp/exercises/pangram/PangramTest.fs +5 -1
  176. data/tracks/fsharp/exercises/queen-attack/QueenAttackTest.fs +7 -7
  177. data/tracks/fsharp/exercises/run-length-encoding/Example.fs +2 -2
  178. data/tracks/fsharp/exercises/run-length-encoding/RunLengthEncodingTest.fs +42 -30
  179. data/tracks/fsharp/generators/Generators.fs +21 -8
  180. data/tracks/gnu-apl/test.apl +4 -4
  181. data/tracks/go/README.md +1 -2
  182. data/tracks/go/config/maintainers.json +5 -6
  183. data/tracks/groovy/config.json +23 -0
  184. data/tracks/groovy/exercises/binary-search/BinarySearch.groovy +14 -0
  185. data/tracks/groovy/exercises/binary-search/BinarySearchSpec.groovy +56 -0
  186. data/tracks/groovy/exercises/binary-search/Example.groovy +43 -0
  187. data/tracks/groovy/exercises/binary-search/README.md +59 -0
  188. data/tracks/groovy/exercises/triangle/Example.groovy +23 -0
  189. data/tracks/groovy/exercises/triangle/README.md +42 -0
  190. data/tracks/groovy/exercises/triangle/Triangle.groovy +15 -0
  191. data/tracks/groovy/exercises/triangle/TriangleSpec.groovy +66 -0
  192. data/tracks/haskell/config.json +9 -0
  193. data/tracks/haskell/exercises/all-your-base/package.yaml +1 -1
  194. data/tracks/haskell/exercises/all-your-base/test/Tests.hs +18 -18
  195. data/tracks/haskell/exercises/bowling/package.yaml +1 -1
  196. data/tracks/haskell/exercises/bowling/test/Tests.hs +9 -9
  197. data/tracks/haskell/exercises/change/package.yaml +1 -1
  198. data/tracks/haskell/exercises/change/test/Tests.hs +5 -0
  199. data/tracks/haskell/exercises/complex-numbers/README.md +92 -0
  200. data/tracks/haskell/exercises/complex-numbers/examples/success-standard/package.yaml +16 -0
  201. data/tracks/haskell/exercises/complex-numbers/examples/success-standard/src/ComplexNumbers.hs +50 -0
  202. data/tracks/haskell/exercises/complex-numbers/package.yaml +20 -0
  203. data/tracks/haskell/exercises/complex-numbers/src/ComplexNumbers.hs +45 -0
  204. data/tracks/haskell/exercises/complex-numbers/stack.yaml +1 -0
  205. data/tracks/haskell/exercises/complex-numbers/test/Tests.hs +194 -0
  206. data/tracks/haskell/exercises/crypto-square/package.yaml +1 -1
  207. data/tracks/haskell/exercises/crypto-square/test/Tests.hs +20 -12
  208. data/tracks/haskell/exercises/dominoes/package.yaml +1 -1
  209. data/tracks/haskell/exercises/forth/package.yaml +1 -1
  210. data/tracks/haskell/exercises/forth/test/Tests.hs +4 -3
  211. data/tracks/haskell/exercises/hamming/package.yaml +1 -1
  212. data/tracks/haskell/exercises/hamming/test/Tests.hs +6 -6
  213. data/tracks/haskell/exercises/isogram/package.yaml +1 -1
  214. data/tracks/haskell/exercises/isogram/test/Tests.hs +2 -2
  215. data/tracks/haskell/exercises/leap/package.yaml +1 -1
  216. data/tracks/haskell/exercises/leap/test/Tests.hs +1 -1
  217. data/tracks/haskell/exercises/pascals-triangle/package.yaml +1 -1
  218. data/tracks/haskell/exercises/pig-latin/examples/success-standard/src/PigLatin.hs +2 -0
  219. data/tracks/haskell/exercises/pig-latin/package.yaml +1 -1
  220. data/tracks/haskell/exercises/pig-latin/test/Tests.hs +8 -0
  221. data/tracks/haskell/exercises/queen-attack/package.yaml +1 -1
  222. data/tracks/haskell/exercises/rna-transcription/package.yaml +1 -1
  223. data/tracks/haskell/exercises/rna-transcription/test/Tests.hs +8 -8
  224. data/tracks/haskell/exercises/robot-simulator/package.yaml +1 -1
  225. data/tracks/haskell/exercises/secret-handshake/package.yaml +1 -1
  226. data/tracks/haskell/exercises/secret-handshake/test/Tests.hs +0 -3
  227. data/tracks/haskell/exercises/sum-of-multiples/package.yaml +1 -1
  228. data/tracks/haskell/exercises/sum-of-multiples/test/Tests.hs +4 -0
  229. data/tracks/haskell/exercises/zipper/package.yaml +1 -1
  230. data/tracks/haskell/exercises/zipper/test/Tests.hs +23 -0
  231. data/tracks/java/config.json +85 -13
  232. data/tracks/java/config/maintainers.json +1 -1
  233. data/tracks/java/exercises/accumulate/README.md +0 -3
  234. data/tracks/java/exercises/acronym/.meta/.version +1 -0
  235. data/tracks/java/exercises/acronym/README.md +0 -1
  236. data/tracks/java/exercises/acronym/src/test/java/AcronymTest.java +0 -3
  237. data/tracks/java/exercises/all-your-base/.meta/.version +1 -0
  238. data/tracks/java/exercises/all-your-base/README.md +1 -1
  239. data/tracks/java/exercises/all-your-base/src/test/java/BaseConverterTest.java +0 -3
  240. data/tracks/java/exercises/allergies/README.md +0 -1
  241. data/tracks/java/exercises/atbash-cipher/README.md +2 -1
  242. data/tracks/java/exercises/beer-song/README.md +1 -1
  243. data/tracks/java/exercises/binary/README.md +2 -0
  244. data/tracks/java/exercises/book-store/README.md +5 -5
  245. data/tracks/java/exercises/bowling/README.md +20 -6
  246. data/tracks/java/exercises/change/.meta/.version +1 -0
  247. data/tracks/java/exercises/change/README.md +1 -1
  248. data/tracks/java/exercises/change/src/test/java/ChangeCalculatorTest.java +0 -3
  249. data/tracks/java/exercises/circular-buffer/README.md +13 -6
  250. data/tracks/java/exercises/clock/.meta/.version +1 -0
  251. data/tracks/java/exercises/clock/src/test/java/ClockAddTest.java +0 -3
  252. data/tracks/java/exercises/clock/src/test/java/ClockCreationTest.java +0 -3
  253. data/tracks/java/exercises/clock/src/test/java/ClockEqualTest.java +0 -3
  254. data/tracks/java/exercises/collatz-conjecture/.meta/.version +1 -0
  255. data/tracks/java/exercises/collatz-conjecture/README.md +1 -1
  256. data/tracks/java/exercises/collatz-conjecture/src/test/java/CollatzCalculatorTest.java +0 -3
  257. data/tracks/java/exercises/complex-numbers/README.md +27 -0
  258. data/tracks/java/exercises/crypto-square/README.md +10 -8
  259. data/tracks/java/exercises/diamond/.meta/.version +1 -0
  260. data/tracks/java/exercises/diamond/README.md +6 -6
  261. data/tracks/java/exercises/diamond/src/test/java/DiamondPrinterTest.java +0 -3
  262. data/tracks/java/exercises/difference-of-squares/.meta/.version +1 -0
  263. data/tracks/java/exercises/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java +0 -3
  264. data/tracks/java/exercises/etl/README.md +2 -0
  265. data/tracks/java/exercises/flatten-array/.meta/.version +1 -0
  266. data/tracks/java/exercises/flatten-array/README.md +1 -2
  267. data/tracks/java/exercises/flatten-array/src/test/java/FlattenerTest.java +0 -3
  268. data/tracks/java/exercises/food-chain/README.md +1 -1
  269. data/tracks/java/exercises/forth/.meta/.version +1 -0
  270. data/tracks/java/exercises/forth/src/test/java/ForthEvaluatorTest.java +0 -3
  271. data/tracks/java/exercises/grade-school/README.md +0 -1
  272. data/tracks/java/exercises/hamming/.meta/.version +1 -0
  273. data/tracks/java/exercises/hamming/src/test/java/HammingTest.java +0 -3
  274. data/tracks/java/exercises/house/README.md +1 -2
  275. data/tracks/java/exercises/isogram/README.md +2 -1
  276. data/tracks/java/exercises/kindergarten-garden/README.md +13 -13
  277. data/tracks/java/exercises/linked-list/README.md +10 -10
  278. data/tracks/java/exercises/list-ops/.meta/.version +1 -0
  279. data/tracks/java/exercises/list-ops/README.md +4 -0
  280. data/tracks/java/exercises/list-ops/src/test/java/ListOpsTest.java +0 -3
  281. data/tracks/java/exercises/luhn/README.md +7 -7
  282. data/tracks/java/exercises/matrix/README.md +6 -4
  283. data/tracks/java/exercises/meetup/README.md +1 -2
  284. data/tracks/java/exercises/minesweeper/.meta/.version +1 -0
  285. data/tracks/java/exercises/minesweeper/src/test/java/MinesweeperBoardTest.java +0 -3
  286. data/tracks/java/exercises/nucleotide-count/README.md +8 -22
  287. data/tracks/java/exercises/ocr-numbers/README.md +5 -5
  288. data/tracks/java/exercises/octal/README.md +6 -2
  289. data/tracks/java/exercises/palindrome-products/README.md +15 -16
  290. data/tracks/java/exercises/pangram/.meta/.version +1 -0
  291. data/tracks/java/exercises/pangram/README.md +1 -1
  292. data/tracks/java/exercises/pangram/src/test/java/PangramCheckerTest.java +0 -3
  293. data/tracks/java/exercises/pascals-triangle/.meta/.version +1 -0
  294. data/tracks/java/exercises/pascals-triangle/README.md +1 -1
  295. data/tracks/java/exercises/pascals-triangle/src/test/java/PascalsTriangleGeneratorTest.java +0 -3
  296. data/tracks/java/exercises/perfect-numbers/.meta/.version +1 -0
  297. data/tracks/java/exercises/perfect-numbers/README.md +2 -2
  298. data/tracks/java/exercises/perfect-numbers/src/test/java/NaturalNumberTest.java +0 -3
  299. data/tracks/java/exercises/phone-number/README.md +3 -2
  300. data/tracks/java/exercises/pythagorean-triplet/README.md +3 -3
  301. data/tracks/java/exercises/queen-attack/README.md +1 -1
  302. data/tracks/java/exercises/rectangles/README.md +7 -7
  303. data/tracks/java/exercises/rna-transcription/.meta/.version +1 -0
  304. data/tracks/java/exercises/rna-transcription/src/test/java/RnaTranscriptionTest.java +0 -3
  305. data/tracks/java/exercises/roman-numerals/README.md +1 -1
  306. data/tracks/java/exercises/rotational-cipher/README.md +2 -1
  307. data/tracks/java/exercises/run-length-encoding/README.md +4 -4
  308. data/tracks/java/exercises/saddle-points/.meta/.version +1 -0
  309. data/tracks/java/exercises/saddle-points/README.md +1 -1
  310. data/tracks/java/exercises/saddle-points/src/test/java/MatrixTest.java +0 -3
  311. data/tracks/java/exercises/scrabble-score/.meta/.version +1 -0
  312. data/tracks/java/exercises/scrabble-score/README.md +3 -1
  313. data/tracks/java/exercises/scrabble-score/src/test/java/ScrabbleScoreTest.java +0 -3
  314. data/tracks/java/exercises/secret-handshake/README.md +1 -1
  315. data/tracks/java/exercises/simple-cipher/README.md +1 -1
  316. data/tracks/java/exercises/simple-linked-list/src/test/java/SimpleLinkedListTest.java +25 -25
  317. data/tracks/java/exercises/space-age/README.md +1 -1
  318. data/tracks/java/exercises/spiral-matrix/.meta/.version +1 -0
  319. data/tracks/java/exercises/spiral-matrix/README.md +2 -2
  320. data/tracks/java/exercises/spiral-matrix/src/test/java/SpiralMatrixBuilderTest.java +0 -3
  321. data/tracks/java/exercises/sum-of-multiples/README.md +0 -3
  322. data/tracks/java/exercises/tournament/README.md +6 -5
  323. data/tracks/java/exercises/transpose/README.md +7 -7
  324. data/tracks/java/exercises/triangle/README.md +9 -6
  325. data/tracks/java/exercises/trinary/README.md +1 -1
  326. data/tracks/java/exercises/twelve-days/README.md +1 -1
  327. data/tracks/java/exercises/two-fer/README.md +1 -2
  328. data/tracks/java/exercises/word-count/README.md +1 -2
  329. data/tracks/java/exercises/word-search/.meta/.version +1 -0
  330. data/tracks/java/exercises/word-search/README.md +1 -1
  331. data/tracks/java/exercises/word-search/src/test/java/WordSearcherTest.java +0 -3
  332. data/tracks/java/exercises/wordy/README.md +0 -5
  333. data/tracks/javascript/config.json +13 -0
  334. data/tracks/javascript/docs/TESTS.md +1 -1
  335. data/tracks/javascript/exercises/diffie-hellman/example.js +1 -1
  336. data/tracks/javascript/exercises/hello-world/example.js +2 -3
  337. data/tracks/javascript/exercises/meetup/example.js +24 -27
  338. data/tracks/javascript/exercises/meetup/meetup.spec.js +0 -6
  339. data/tracks/javascript/exercises/nucleotide-count/nucleotide-count.spec.js +1 -1
  340. data/tracks/javascript/exercises/protein-translation/README.md +73 -0
  341. data/tracks/javascript/exercises/protein-translation/example.js +68 -0
  342. data/tracks/javascript/exercises/protein-translation/protein-translation.spec.js +63 -0
  343. data/tracks/julia/README.md +1 -1
  344. data/tracks/kotlin/config.json +11 -0
  345. data/tracks/kotlin/exercises/acronym/README.md +0 -1
  346. data/tracks/kotlin/exercises/all-your-base/README.md +1 -1
  347. data/tracks/kotlin/exercises/allergies/README.md +0 -1
  348. data/tracks/kotlin/exercises/atbash-cipher/README.md +2 -1
  349. data/tracks/kotlin/exercises/beer-song/README.md +1 -1
  350. data/tracks/kotlin/exercises/binary/README.md +2 -0
  351. data/tracks/kotlin/exercises/change/README.md +1 -1
  352. data/tracks/kotlin/exercises/collatz-conjecture/README.md +1 -1
  353. data/tracks/kotlin/exercises/complex-numbers/README.md +27 -0
  354. data/tracks/kotlin/exercises/diamond/README.md +6 -6
  355. data/tracks/kotlin/exercises/etl/README.md +2 -0
  356. data/tracks/kotlin/exercises/flatten-array/README.md +1 -2
  357. data/tracks/kotlin/exercises/grade-school/README.md +0 -1
  358. data/tracks/kotlin/exercises/grains/README.md +0 -1
  359. data/tracks/kotlin/exercises/hello-world/.meta/hints.md +4 -0
  360. data/tracks/kotlin/exercises/hello-world/.meta/src/reference/kotlin/HelloWorld.kt +2 -2
  361. data/tracks/kotlin/exercises/hello-world/README.md +6 -0
  362. data/tracks/kotlin/exercises/hello-world/TUTORIAL.md +32 -434
  363. data/tracks/kotlin/exercises/hello-world/src/main/kotlin/HelloWorld.kt +1 -1
  364. data/tracks/kotlin/exercises/hello-world/src/test/kotlin/HelloWorldTest.kt +2 -21
  365. data/tracks/kotlin/exercises/isogram/README.md +2 -1
  366. data/tracks/kotlin/exercises/leap/README.md +1 -1
  367. data/tracks/kotlin/exercises/linked-list/README.md +10 -10
  368. data/tracks/kotlin/exercises/luhn/README.md +7 -7
  369. data/tracks/kotlin/exercises/meetup/README.md +1 -2
  370. data/tracks/kotlin/exercises/nucleotide-count/README.md +8 -22
  371. data/tracks/kotlin/exercises/pangram/README.md +1 -1
  372. data/tracks/kotlin/exercises/pascals-triangle/README.md +1 -1
  373. data/tracks/kotlin/exercises/perfect-numbers/README.md +2 -2
  374. data/tracks/kotlin/exercises/phone-number/README.md +3 -2
  375. data/tracks/kotlin/exercises/roman-numerals/README.md +1 -1
  376. data/tracks/kotlin/exercises/rotational-cipher/README.md +2 -1
  377. data/tracks/kotlin/exercises/saddle-points/README.md +1 -1
  378. data/tracks/kotlin/exercises/scrabble-score/README.md +3 -1
  379. data/tracks/kotlin/exercises/secret-handshake/README.md +1 -1
  380. data/tracks/kotlin/exercises/settings.gradle +1 -0
  381. data/tracks/kotlin/exercises/space-age/README.md +1 -2
  382. data/tracks/kotlin/exercises/spiral-matrix/README.md +2 -2
  383. data/tracks/kotlin/exercises/sum-of-multiples/README.md +0 -3
  384. data/tracks/kotlin/exercises/triangle/README.md +9 -6
  385. data/tracks/kotlin/exercises/two-fer/.meta/src/reference/kotlin/Twofer.kt +3 -0
  386. data/tracks/kotlin/exercises/two-fer/README.md +50 -0
  387. data/tracks/kotlin/exercises/two-fer/build.gradle +28 -0
  388. data/tracks/kotlin/exercises/two-fer/src/main/kotlin/.keep +0 -0
  389. data/tracks/kotlin/exercises/two-fer/src/test/kotlin/TwoferTest.kt +31 -0
  390. data/tracks/kotlin/exercises/word-count/README.md +1 -2
  391. data/tracks/ocaml/exercises/pangram/test.ml +3 -1
  392. data/tracks/perl5/.travis.yml +3 -1
  393. data/tracks/php/Makefile +2 -2
  394. data/tracks/php/README.md +4 -4
  395. data/tracks/php/config.json +15 -0
  396. data/tracks/php/exercises/transpose/example.php +30 -0
  397. data/tracks/php/exercises/transpose/transpose_test.php +116 -0
  398. data/tracks/php/{phpcs-xphp.xml → phpcs-php.xml} +0 -0
  399. data/tracks/python/.travis.yml +1 -1
  400. data/tracks/python/config.json +199 -39
  401. data/tracks/python/exercises/acronym/acronym_test.py +1 -1
  402. data/tracks/python/exercises/allergies/allergies_test.py +1 -1
  403. data/tracks/python/exercises/alphametics/alphametics_test.py +1 -1
  404. data/tracks/python/exercises/anagram/anagram_test.py +1 -1
  405. data/tracks/python/exercises/atbash-cipher/atbash_cipher_test.py +1 -1
  406. data/tracks/python/exercises/bob/bob.py +1 -1
  407. data/tracks/python/exercises/bob/bob_test.py +1 -1
  408. data/tracks/python/exercises/book-store/book_store_test.py +1 -1
  409. data/tracks/python/exercises/bracket-push/bracket_push.py +1 -1
  410. data/tracks/python/exercises/bracket-push/bracket_push_test.py +1 -1
  411. data/tracks/python/exercises/collatz-conjecture/collatz_conjecture_test.py +1 -1
  412. data/tracks/python/exercises/diamond/diamond_test.py +1 -1
  413. data/tracks/python/exercises/difference-of-squares/difference_of_squares_test.py +1 -1
  414. data/tracks/python/exercises/diffie-hellman/README.md +58 -0
  415. data/tracks/python/exercises/diffie-hellman/diffie_hellman.py +10 -0
  416. data/tracks/python/exercises/diffie-hellman/diffie_hellman_test.py +87 -0
  417. data/tracks/python/exercises/diffie-hellman/example.py +13 -0
  418. data/tracks/python/exercises/etl/etl_test.py +1 -1
  419. data/tracks/python/exercises/food-chain/README.md +81 -0
  420. data/tracks/python/exercises/food-chain/example.py +45 -0
  421. data/tracks/python/exercises/food-chain/food_chain.py +2 -0
  422. data/tracks/python/exercises/food-chain/food_chain_test.py +109 -0
  423. data/tracks/python/exercises/forth/README.md +43 -0
  424. data/tracks/python/exercises/forth/example.py +58 -0
  425. data/tracks/python/exercises/forth/forth.py +2 -0
  426. data/tracks/python/exercises/forth/forth_test.py +254 -0
  427. data/tracks/python/exercises/gigasecond/gigasecond_test.py +1 -1
  428. data/tracks/python/exercises/grep/grep_test.py +1 -1
  429. data/tracks/python/exercises/hello-world/hello_world_test.py +1 -1
  430. data/tracks/python/exercises/isogram/isogram_test.py +10 -10
  431. data/tracks/python/exercises/largest-series-product/largest_series_product_test.py +1 -1
  432. data/tracks/python/exercises/leap/leap_test.py +5 -5
  433. data/tracks/python/exercises/luhn/luhn_test.py +16 -16
  434. data/tracks/python/exercises/markdown/README.md +30 -0
  435. data/tracks/python/exercises/markdown/example.py +80 -0
  436. data/tracks/python/exercises/markdown/markdown.py +71 -0
  437. data/tracks/python/exercises/markdown/markdown_test.py +51 -0
  438. data/tracks/python/exercises/meetup/meetup_test.py +1 -1
  439. data/tracks/python/exercises/nth-prime/nth_prime_test.py +1 -1
  440. data/tracks/python/exercises/pascals-triangle/pascals_triangle_test.py +2 -2
  441. data/tracks/python/exercises/perfect-numbers/perfect_numbers_test.py +11 -11
  442. data/tracks/python/exercises/phone-number/phone_number_test.py +1 -1
  443. data/tracks/python/exercises/prime-factors/prime_factors_test.py +1 -1
  444. data/tracks/python/exercises/pythagorean-triplet/pythagorean_triplet_test.py +3 -3
  445. data/tracks/python/exercises/queen-attack/queen_attack_test.py +8 -8
  446. data/tracks/python/exercises/rail-fence-cipher/rail_fence_cipher_test.py +1 -1
  447. data/tracks/python/exercises/rectangles/rectangles_test.py +1 -1
  448. data/tracks/python/exercises/robot-simulator/robot_simulator.py +9 -1
  449. data/tracks/python/exercises/roman-numerals/roman_numerals_test.py +1 -1
  450. data/tracks/python/exercises/run-length-encoding/run_length_encoding_test.py +1 -1
  451. data/tracks/python/exercises/say/say_test.py +1 -1
  452. data/tracks/python/exercises/scrabble-score/scrabble_score_test.py +1 -1
  453. data/tracks/python/exercises/series/series.py +1 -1
  454. data/tracks/python/exercises/sieve/sieve_test.py +1 -1
  455. data/tracks/python/exercises/sublist/sublist_test.py +1 -1
  456. data/tracks/python/exercises/tournament/tournament_test.py +1 -1
  457. data/tracks/python/exercises/transpose/transpose_test.py +1 -1
  458. data/tracks/python/exercises/two-bucket/example.py +49 -54
  459. data/tracks/python/exercises/two-bucket/two_bucket_test.py +1 -1
  460. data/tracks/python/exercises/variable-length-quantity/variable_length_quantity_test.py +1 -1
  461. data/tracks/rust/config.json +24 -0
  462. data/tracks/rust/exercises/collatz-conjecture/Cargo.lock +4 -0
  463. data/tracks/rust/exercises/collatz-conjecture/Cargo.toml +3 -0
  464. data/tracks/rust/exercises/collatz-conjecture/README.md +65 -0
  465. data/tracks/rust/exercises/collatz-conjecture/example.rs +19 -0
  466. data/tracks/rust/exercises/collatz-conjecture/src/lib.rs +4 -0
  467. data/tracks/rust/exercises/collatz-conjecture/tests/collatz-conjecture.rs +32 -0
  468. data/tracks/rust/exercises/decimal/.gitignore +7 -0
  469. data/tracks/rust/exercises/decimal/.meta/description.md +19 -0
  470. data/tracks/rust/exercises/decimal/.meta/metadata.yml +3 -0
  471. data/tracks/rust/exercises/decimal/Cargo-example.toml +9 -0
  472. data/tracks/rust/exercises/decimal/Cargo.toml +6 -0
  473. data/tracks/rust/exercises/decimal/README.md +59 -0
  474. data/tracks/rust/exercises/decimal/example.rs +187 -0
  475. data/tracks/rust/exercises/decimal/src/lib.rs +10 -0
  476. data/tracks/rust/exercises/decimal/tests/decimal.rs +332 -0
  477. data/tracks/sml/exercises/accumulate/README.md +9 -1
  478. data/tracks/swift/exercises/luhn/Sources/LuhnExample.swift +17 -26
  479. data/tracks/swift/exercises/luhn/Tests/LinuxMain.swift +1 -1
  480. data/tracks/swift/exercises/luhn/Tests/LuhnTests/LuhnTests.swift +59 -35
  481. data/tracks/typescript/config.json +34 -0
  482. data/tracks/typescript/exercises/binary-search/README.md +67 -0
  483. data/tracks/typescript/exercises/binary-search/binary-search.example.ts +42 -0
  484. data/tracks/typescript/exercises/binary-search/binary-search.test.ts +27 -0
  485. data/tracks/typescript/exercises/binary-search/binary-search.ts +3 -0
  486. data/tracks/typescript/exercises/binary-search/package.json +36 -0
  487. data/tracks/typescript/exercises/binary-search/tsconfig.json +22 -0
  488. data/tracks/typescript/exercises/binary-search/tslint.json +127 -0
  489. data/tracks/typescript/exercises/binary-search/yarn.lock +2305 -0
  490. data/tracks/typescript/exercises/pascals-triangle/README.md +47 -0
  491. data/tracks/typescript/exercises/pascals-triangle/package.json +36 -0
  492. data/tracks/typescript/exercises/pascals-triangle/pascals-triangle.example.ts +32 -0
  493. data/tracks/typescript/exercises/pascals-triangle/pascals-triangle.test.ts +28 -0
  494. data/tracks/typescript/exercises/pascals-triangle/pascals-triangle.ts +2 -0
  495. data/tracks/typescript/exercises/pascals-triangle/tsconfig.json +22 -0
  496. data/tracks/typescript/exercises/pascals-triangle/tslint.json +127 -0
  497. data/tracks/typescript/exercises/pascals-triangle/yarn.lock +2305 -0
  498. data/tracks/typescript/exercises/rotational-cipher/README.md +63 -0
  499. data/tracks/typescript/exercises/rotational-cipher/package.json +36 -0
  500. data/tracks/typescript/exercises/rotational-cipher/rotational-cipher.example.ts +19 -0
  501. data/tracks/typescript/exercises/rotational-cipher/rotational-cipher.test.ts +56 -0
  502. data/tracks/typescript/exercises/rotational-cipher/rotational-cipher.ts +1 -0
  503. data/tracks/typescript/exercises/rotational-cipher/tsconfig.json +22 -0
  504. data/tracks/typescript/exercises/rotational-cipher/tslint.json +127 -0
  505. data/tracks/typescript/exercises/rotational-cipher/yarn.lock +2305 -0
  506. metadata +171 -5
  507. data/tracks/javascript/exercises/twelve-days/package.json +0 -69
  508. data/tracks/kotlin/exercises/hello-world/GETTING_STARTED.md +0 -50
@@ -0,0 +1,63 @@
1
+ var translate = require('./protein-translation');
2
+
3
+ describe('ProteinTranslation', function() {
4
+ it('Empty RNA has no proteins', function() {
5
+ expect(translate()).toEqual([]);
6
+ });
7
+
8
+ xit('Methionine codon translates into protein', function () {
9
+ expect(translate('AUG')).toEqual(["Methionine"]);
10
+ });
11
+
12
+ xit('Phenylalanine codons translate into protein', function () {
13
+ expect(translate('UUUUUC')).toEqual(["Phenylalanine", "Phenylalanine"]);
14
+ });
15
+
16
+ xit('Leucine codons translate into protein', function () {
17
+ expect(translate('UUAUUG')).toEqual(["Leucine", "Leucine"]);
18
+ });
19
+
20
+ xit('Serine codons translate into protein', function () {
21
+ expect(translate('UCUUCCUCAUCG')).toEqual(["Serine", "Serine", "Serine", "Serine"]);
22
+ });
23
+
24
+ xit('Tyrosine codons translate into protein', function () {
25
+ expect(translate('UAUUAC')).toEqual(["Tyrosine", "Tyrosine"]);
26
+ });
27
+
28
+ xit('Cysteine codons translate into protein', function() {
29
+ expect(translate('UGUUGC')).toEqual(["Cysteine", "Cysteine"]);
30
+ });
31
+
32
+ xit('Tryptophan codon translates into protein', function () {
33
+ expect(translate('UGG')).toEqual(["Tryptophan"]);
34
+ });
35
+
36
+ xit('Sequence starts with stop codon 1', function () {
37
+ expect(translate('UAAUUUUUA')).toEqual([]);
38
+ });
39
+
40
+ xit('Sequence starts with stop codon 2', function () {
41
+ expect(translate('UAGAUGUAU')).toEqual([]);
42
+ });
43
+
44
+ xit('Sequence starts with stop codon 3', function () {
45
+ expect(translate('UGAUGU')).toEqual([]);
46
+ });
47
+
48
+ xit('Small RNA strand', function () {
49
+ expect(translate('AUGUUUUCU')).toEqual(["Methionine", "Phenylalanine", "Serine"]);
50
+ });
51
+
52
+ xit('Stop codon ends translation', function () {
53
+ expect(translate('AUGUUUUCUUAAAUG')).toEqual(["Methionine", "Phenylalanine", "Serine"]);
54
+ });
55
+
56
+ xit('Invalid codon throws error', function () {
57
+ expect(
58
+ function() {
59
+ translate('LOL')
60
+ }
61
+ ).toThrow(new Error("Invalid codon"));
62
+ })
63
+ });
@@ -1,6 +1,6 @@
1
1
  # Exercism Julia Track
2
2
 
3
- [![Join the chat at https://gitter.im/exercism/julia](https://badges.gitter.im/exercism/julia.svg)](https://gitter.im/exercism/julia?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
3
+ [![Join the chat at https://gitter.im/exercism/xjulia](https://badges.gitter.im/exercism/xjulia.svg)](https://gitter.im/exercism/xjulia?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
4
  [![Build Status](https://travis-ci.org/exercism/julia.svg?branch=master)](https://travis-ci.org/exercism/julia)
5
5
 
6
6
  Exercism exercises in Julia.
@@ -15,6 +15,16 @@
15
15
 
16
16
  ]
17
17
  },
18
+ {
19
+ "uuid": "fa4194c5-084d-f780-4db6-707ef7bcc30c00e9ee5",
20
+ "slug": "two-fer",
21
+ "core": false,
22
+ "unlocked_by": null,
23
+ "difficulty": 2,
24
+ "topics": [
25
+
26
+ ]
27
+ },
18
28
  {
19
29
  "uuid": "9772c916-c619-445c-834d-af7dbf1ad2d9",
20
30
  "slug": "rna-transcription",
@@ -633,3 +643,4 @@
633
643
  ],
634
644
  "solution_pattern": "reference"
635
645
  }
646
+
@@ -7,7 +7,6 @@ Techies love their TLA (Three Letter Acronyms)!
7
7
  Help generate some jargon by writing a program that converts a long name
8
8
  like Portable Network Graphics to its acronym (PNG).
9
9
 
10
-
11
10
 
12
11
 
13
12
  ## Source
@@ -6,6 +6,7 @@ Implement general base conversion. Given a number in base **a**,
6
6
  represented as a sequence of digits, convert it to base **b**.
7
7
 
8
8
  ## Note
9
+
9
10
  - Try to implement the conversion yourself.
10
11
  Do not use something else to perform the conversion for you.
11
12
 
@@ -28,7 +29,6 @@ The number 1120, *in base 3*, means:
28
29
 
29
30
  I think you got the idea!
30
31
 
31
-
32
32
  *Yes. Those three numbers above are exactly the same. Congratulations!*
33
33
 
34
34
 
@@ -29,7 +29,6 @@ allergens that score 256, 512, 1024, etc.). Your program should
29
29
  ignore those components of the score. For example, if the allergy
30
30
  score is 257, your program should only report the eggs (1) allergy.
31
31
 
32
-
33
32
 
34
33
 
35
34
  ## Source
@@ -9,7 +9,7 @@ letter, the second with the second-last, and so on.
9
9
 
10
10
  An Atbash cipher for the Latin alphabet would be as follows:
11
11
 
12
- ```plain
12
+ ```text
13
13
  Plain: abcdefghijklmnopqrstuvwxyz
14
14
  Cipher: zyxwvutsrqponmlkjihgfedcba
15
15
  ```
@@ -23,6 +23,7 @@ being 5 letters, and punctuation is excluded. This is to make it harder to guess
23
23
  things based on word boundaries.
24
24
 
25
25
  ## Examples
26
+
26
27
  - Encoding `test` gives `gvhg`
27
28
  - Decoding `gvhg` gives `test`
28
29
  - Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog`
@@ -4,7 +4,7 @@ Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles
4
4
 
5
5
  Note that not all verses are identical.
6
6
 
7
- ```plain
7
+ ```text
8
8
  99 bottles of beer on the wall, 99 bottles of beer.
9
9
  Take one down and pass it around, 98 bottles of beer on the wall.
10
10
 
@@ -7,10 +7,12 @@ string, your program should produce a decimal output. The
7
7
  program should handle invalid inputs.
8
8
 
9
9
  ## Note
10
+
10
11
  - Implement the conversion yourself.
11
12
  Do not use something else to perform the conversion for you.
12
13
 
13
14
  ## About Binary (Base-2)
15
+
14
16
  Decimal is a base-10 system.
15
17
 
16
18
  A number 23 in base 10 notation can be understood
@@ -20,7 +20,7 @@ that the sum of the coins' value would equal the correct amount of change.
20
20
 
21
21
  ## Source
22
22
 
23
- Software Craftsmanship - Kata-logue [http://craftsmanship.sv.cmu.edu/exercises/coin-change-kata](http://craftsmanship.sv.cmu.edu/exercises/coin-change-kata)
23
+ Software Craftsmanship - Coin Change Kata [https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata](https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata)
24
24
 
25
25
  ## Submitting Incomplete Solutions
26
26
  It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -10,6 +10,7 @@ always reach 1 eventually.
10
10
  Given a number n, return the number of steps required to reach 1.
11
11
 
12
12
  ## Examples
13
+
13
14
  Starting with n = 12, the steps would be as follows:
14
15
 
15
16
  0. 12
@@ -25,7 +26,6 @@ Starting with n = 12, the steps would be as follows:
25
26
 
26
27
  Resulting in 9 steps. So for input n = 12, the return value would be 9.
27
28
 
28
-
29
29
 
30
30
 
31
31
  ## Source
@@ -2,6 +2,33 @@
2
2
 
3
3
  A complex number is a number in the form `a + b * i` where `a` and `b` are real and `i` satisfies `i^2 = -1`.
4
4
 
5
+ `a` is called the real part and `b` is called the imaginary part of `z`.
6
+ The conjugate of the number `a + b * i` is the number `a - b * i`.
7
+ The absolute value of a complex number `z = a + b * i` is a real number `|z| = sqrt(a^2 + b^2)`. The square of the absolute value `|z|^2` is the result of multiplication of `z` by its complex conjugate.
8
+
9
+ The sum/difference of two complex numbers involves adding/subtracting their real and imaginary parts separately:
10
+ `(a + i * b) + (c + i * d) = (a + c) + (b + d) * i`,
11
+ `(a + i * b) - (c + i * d) = (a - c) + (b - d) * i`.
12
+
13
+ Multiplication result is by definition
14
+ `(a + i * b) * (c + i * d) = (a * c - b * d) + (b * c + a * d) * i`.
15
+
16
+ The reciprocal of a non-zero complex number is
17
+ `1 / (a + i * b) = a/(a^2 + b^2) - b/(a^2 + b^2) * i`.
18
+
19
+ Dividing a complex number `a + i * b` by another `c + i * d` gives:
20
+ `(a + i * b) / (c + i * d) = (a * c + b * d)/(c^2 + d^2) + (b * c - a * d)/(c^2 + d^2) * i`.
21
+
22
+ Exponent of a complex number can be expressed as
23
+ `exp(a + i * b) = exp(a) * exp(i * b)`,
24
+ and the last term is given by Euler's formula `exp(i * b) = cos(b) + i * sin(b)`.
25
+
26
+
27
+ Implement the following operations:
28
+ - addition, subtraction, multiplication and division of two complex numbers,
29
+ - conjugate, absolute value, exponent of a given complex number.
30
+
31
+
5
32
  Assume the programming language you are using does not have an implementation of complex numbers.
6
33
 
7
34
 
@@ -1,7 +1,7 @@
1
1
  # Diamond
2
2
 
3
- The diamond kata takes as its input a letter, and outputs it in a diamond
4
- shape. Given a letter, it prints a diamond starting with 'A', with the
3
+ The diamond kata takes as its input a letter, and outputs it in a diamond
4
+ shape. Given a letter, it prints a diamond starting with 'A', with the
5
5
  supplied letter at the widest point.
6
6
 
7
7
  ## Requirements
@@ -15,7 +15,7 @@ supplied letter at the widest point.
15
15
  * The diamond has a square shape (width equals height).
16
16
  * The letters form a diamond shape.
17
17
  * The top half has the letters in ascending order.
18
- * The bottom half has the letters in descending order.
18
+ * The bottom half has the letters in descending order.
19
19
  * The four corners (containing the spaces) are triangles.
20
20
 
21
21
  ## Examples
@@ -24,13 +24,13 @@ In the following examples, spaces are indicated by `·` characters.
24
24
 
25
25
  Diamond for letter 'A':
26
26
 
27
- ```plain
27
+ ```text
28
28
  A
29
29
  ```
30
30
 
31
31
  Diamond for letter 'C':
32
32
 
33
- ```plain
33
+ ```text
34
34
  ··A··
35
35
  ·B·B·
36
36
  C···C
@@ -40,7 +40,7 @@ C···C
40
40
 
41
41
  Diamond for letter 'E':
42
42
 
43
- ```plain
43
+ ```text
44
44
  ····A····
45
45
  ···B·B···
46
46
  ··C···C··
@@ -3,6 +3,7 @@
3
3
  We are going to do the `Transform` step of an Extract-Transform-Load.
4
4
 
5
5
  ### ETL
6
+
6
7
  Extract-Transform-Load (ETL) is a fancy way of saying, "We have some crufty, legacy data over in this system, and now we need it in this shiny new system over here, so
7
8
  we're going to migrate this."
8
9
 
@@ -11,6 +12,7 @@ once." That's then typically followed by much forehead slapping and
11
12
  moaning about how stupid we could possibly be.)
12
13
 
13
14
  ### The goal
15
+
14
16
  We're going to extract some scrabble scores from a legacy system.
15
17
 
16
18
  The old system stored a list of letters per score:
@@ -3,14 +3,13 @@
3
3
  Take a nested list and return a single flattened list with all values except nil/null.
4
4
 
5
5
  The challenge is to write a function that accepts an arbitrarily-deep nested list-like structure and returns a flattened structure without any nil/null values.
6
-
6
+
7
7
  For Example
8
8
 
9
9
  input: [1,[2,3,null,4],[null],5]
10
10
 
11
11
  output: [1,2,3,4,5]
12
12
 
13
-
14
13
 
15
14
 
16
15
  ## Source
@@ -21,7 +21,6 @@ In the end, you should be able to:
21
21
  Note that all our students only have one name. (It's a small town, what
22
22
  do you want?)
23
23
 
24
-
25
24
  ## For bonus points
26
25
 
27
26
  Did you get the tests passing and the code clean? If you want to, these
@@ -15,7 +15,6 @@ Write code that shows:
15
15
  - how many grains were on each square, and
16
16
  - the total number of grains
17
17
 
18
-
19
18
  ## For bonus points
20
19
 
21
20
  Did you get the tests passing and the code clean? If you want to, these
@@ -0,0 +1,4 @@
1
+ Since this is your first Kotlin exercise, we've included a detailed TUTORIAL.md
2
+ file that guides you through your solution. Check it out for tips and
3
+ assistance!
4
+
@@ -1,3 +1,3 @@
1
- fun hello(name: String = "World"): String {
2
- return "Hello, ${if (name.isBlank()) "World" else name}!"
1
+ fun hello(): String {
2
+ return "Hello, World!"
3
3
  }
@@ -14,6 +14,12 @@ The objectives are simple:
14
14
 
15
15
  If everything goes well, you will be ready to fetch your first real exercise.
16
16
 
17
+ Since this is your first Kotlin exercise, we've included a detailed TUTORIAL.md
18
+ file that guides you through your solution. Check it out for tips and
19
+ assistance!
20
+
21
+
22
+
17
23
 
18
24
 
19
25
  ## Source
@@ -1,22 +1,15 @@
1
1
  NOTE: You can also view the HTML version of this file here:
2
2
  https://github.com/exercism/kotlin/blob/master/exercises/hello-world/TUTORIAL.md
3
3
 
4
+ * [Introduction](#introduction)
5
+ * [Exercise Structure](#exercise-structure)
4
6
  * [Solving "Hello, World!"](#solving-hello-world)
5
- * [Reading Gradle output](#reading-gradle-output)
6
- * [Fixing the first failing test](#fixing-the-first-failing-test)
7
- * [Enabling and fixing the second test](#enabling-and-fixing-the-second-test)
8
- * [Enabling and fixing the third test](#enabling-and-fixing-the-third-test)
9
- * [Enabling the last test](#enabling-the-last-test)
10
- * [Refactoring](#refactoring)
11
7
  * [Submitting your first iteration](#submitting-your-first-iteration)
12
8
  * [Next Steps](#next-steps)
13
- * [Review (and comment on) others' submissions to this exercise](#review-and-comment-on-others-submissions-to-this-exercise)
14
- * [Extend an exercise](#extend-an-exercise)
15
- * [Contribute to Exercism](#contribute-to-exercism)
16
9
 
17
10
  ----
18
11
 
19
- # Solving "Hello, World!"
12
+ # Introduction
20
13
 
21
14
  Welcome to the first exercise on the Kotlin track!
22
15
 
@@ -35,7 +28,22 @@ left off. If you haven't reviewed those instructions, do so now.
35
28
 
36
29
  The following instructions work equally well on Windows, Mac OS X and Linux.
37
30
 
38
- ## Reading Gradle output
31
+ # Exercise Structure
32
+
33
+ When you fetch a new Kotlin exercise, you will receive:
34
+
35
+ * __one or more test files__ (always). These live in the `src/test/kotlin`
36
+ directory and define a set of tests that our solution must satisfy before we
37
+ can safely declare that it is working.
38
+ * __one or more starter files__ (initially). If provided, these live in the
39
+ `src/main/kotlin` directory and define shells of the classes you will need
40
+ in order to solve the current problem.
41
+
42
+
43
+
44
+ # Solving "Hello World!"
45
+
46
+ ## Step 1: Run the tests against the starter solution
39
47
 
40
48
  Use Gradle to run the tests:
41
49
 
@@ -84,19 +92,14 @@ running the task you asked it to: executing the tests against the solution.
84
92
  ```
85
93
  :test
86
94
 
87
- HelloWorldTest > helloSampleName SKIPPED
88
95
 
89
- HelloWorldTest > helloBlankName SKIPPED
90
-
91
- HelloWorldTest > helloNoName FAILED
96
+ HelloWorldTest > helloWorldTest FAILED
92
97
  org.junit.ComparisonFailure: expected:<[Hello, World!]> but was:<[]>
93
98
  at org.junit.Assert.assertEquals(Assert.java:115)
94
99
  at org.junit.Assert.assertEquals(Assert.java:144)
95
100
  at HelloWorldTest.helloNoName(HelloWorldTest.kt:10)
96
101
 
97
- HelloWorldTest > helloAnotherSampleName SKIPPED
98
-
99
- 4 tests completed, 1 failed, 3 skipped
102
+ 1 test completed, 1 failed
100
103
  :test FAILED
101
104
 
102
105
  FAILURE: Build failed with an exception.
@@ -113,19 +116,19 @@ BUILD FAILED
113
116
  Total time: 7.473 secs
114
117
  ```
115
118
 
116
- Seeing the word "fail" NINE TIMES might give you the impression you've done
119
+ Seeing the word "fail" might give you the impression you've done
117
120
  something horribly wrong! You haven't. It's a whole lot of noise over
118
121
  a single test not passing.
119
122
 
120
123
  Let's focus in on the important bits:
121
124
 
122
125
  ```
123
- HelloWorldTest > helloNoName FAILED
126
+ HelloWorldTest > helloWorldTest FAILED
124
127
  org.junit.ComparisonFailure: expected:<[Hello, World!]> but was:<[]>
125
128
  ```
126
129
 
127
130
  ...is read: "Within the test class named `HelloWorldTest`, the test method
128
- `helloNoName` did not pass because the solution did not satisfy an
131
+ `helloWorldTest` did not pass because the solution did not satisfy an
129
132
  assertion. Apparently, we expected to see the string 'Hello, World!' but
130
133
  a blank string was returned instead.
131
134
 
@@ -133,7 +136,7 @@ The last line of the stack trace tells us exactly where this unsatisfied
133
136
  assertion lives:
134
137
 
135
138
  ```
136
- at HelloWorldTest.helloNoName(HelloWorldTest.kt:10)
139
+ at HelloWorldTest.helloWorldTest(HelloWorldTest.kt:10)
137
140
  ```
138
141
 
139
142
  Looks like the scene of the crime is on line 10 in the test file.
@@ -145,25 +148,22 @@ Knowing these two facts,
145
148
 
146
149
  we can turn this failure into success.
147
150
 
148
-
149
-
150
- ## Fixing the first failing test
151
+ ## Step 2: Fix the Test!
151
152
 
152
153
  In your favorite text editor, open `src/test/kotlin/HelloWorldTest.kt`
153
154
  and go to line 10.
154
155
 
155
156
  ```kotlin
156
- assertEquals("Hello, World!", hello(""))
157
+ assertEquals("Hello, World!", hello())
157
158
  ```
158
159
 
159
- The test is expecting that `hello()`, when given an empty string (`""`),
160
- returns "Hello, World!". Instead, `hello()` is returning `""`.
160
+ The test is expecting that `hello()`, returns "Hello, World!". Instead, `hello()` is returning `""`.
161
161
  Let's fix that.
162
162
 
163
163
  Open `src/main/kotlin/HelloWorld.kt`.
164
164
 
165
165
  ```kotlin
166
- fun hello(name: String = ""): String {
166
+ fun hello(): String {
167
167
  return ""
168
168
  }
169
169
  ```
@@ -171,7 +171,7 @@ fun hello(name: String = ""): String {
171
171
  Let's change that to return the expected string:
172
172
 
173
173
  ```kotlin
174
- fun hello(name: String = ""): String {
174
+ fun hello(): String {
175
175
  return "Hello, World!"
176
176
  }
177
177
  ```
@@ -181,7 +181,6 @@ Save the file and run the tests again:
181
181
  ```
182
182
  $ gradle test
183
183
  :compileKotlin
184
- w: /Users/jtigger/exercism/exercises/kotlin/hello-world/src/main/kotlin/HelloWorld.kt: (1, 11): Parameter 'name' is never used
185
184
  :compileJava UP-TO-DATE
186
185
  :copyMainKotlinClasses
187
186
  :processResources UP-TO-DATE
@@ -193,419 +192,18 @@ w: /Users/jtigger/exercism/exercises/kotlin/hello-world/src/main/kotlin/HelloWor
193
192
  :testClasses UP-TO-DATE
194
193
  :test
195
194
 
196
- HelloWorldTest > helloSampleName SKIPPED
197
-
198
- HelloWorldTest > helloBlankName SKIPPED
199
-
200
- HelloWorldTest > helloNoName PASSED
201
-
202
- HelloWorldTest > helloAnotherSampleName SKIPPED
195
+ HelloWorldTest > helloWorldTest PASSED
203
196
 
204
197
  BUILD SUCCESSFUL
205
198
 
206
199
  Total time: 7.318 secs
207
200
  ```
208
201
 
209
- "BUILD SUCCESSFUL"! Woohoo! :) You can see that `helloNoName()` test is
202
+ "BUILD SUCCESSFUL"! Woohoo! :) You can see that `helloWorldTest()` test is
210
203
  now passing.
211
204
 
212
- We still see the warning about `name` not being used; we'll get to that
213
- next.
214
-
215
- With one win under our belt, we can turn our focus to some other messages
216
- that we've been ignoring: the lines ending in "`SKIPPED`".
217
-
218
- Each test suite contains a series of tests, all of which have been marked
219
- to be skipped/ignored except the first one. We did this to help you focus
220
- on getting one test running at a time.
221
-
222
- Let's tackle the next test...
223
-
224
-
225
-
226
- ## Enabling and fixing the second test
227
-
228
- Right now, that second test is being skipped/ignored. Let's enable it.
229
-
230
- (Re)open `src/test/kotlin/HelloWorldTest.kt` and find the second test:
231
-
232
- ```kotlin
233
- @Test
234
- @Ignore
235
- fun helloSampleName() {
236
- assertEquals("Hello, Alice!", hello("Alice"))
237
- }
238
- ```
239
-
240
- When the JUnit test runner sees that `@Ignore` annotation on the test
241
- method, it knows to skip over that test. Remove that line:
242
-
243
- ```kotlin
244
- @Test
245
- fun helloSampleName() {
246
- assertEquals("Hello, Alice!", hello("Alice"))
247
- }
248
- ```
249
-
250
- Now, when you run the tests, both tests run:
251
-
252
- ```
253
- $ gradle test
254
- :test
255
-
256
- HelloWorldTest > helloSampleName FAILED
257
- org.junit.ComparisonFailure: expected:<Hello, [Alice]!> but was:<Hello, [World]!>
258
- at org.junit.Assert.assertEquals(Assert.java:115)
259
- at org.junit.Assert.assertEquals(Assert.java:144)
260
- at HelloWorldTest.helloSampleName(HelloWorldTest.kt:15)
261
-
262
- HelloWorldTest > helloBlankName SKIPPED
263
-
264
- HelloWorldTest > helloNoName PASSED
265
-
266
- HelloWorldTest > helloAnotherSampleName SKIPPED
267
-
268
- 4 tests completed, 1 failed, 2 skipped
269
- ```
270
-
271
- The first test, `helloNoName()` continues to pass. We see that
272
- `helloSampleName` -- the test we just un-`@Ignore`'d -- is now running and
273
- failing. Yay, failing test! In fact, the "failure" message is just
274
- describing the difference between what the program does now and what it
275
- should do for us to call it "done."
276
-
277
- Right now, we've hardcoded the greeting. Enabling this second test has
278
- unleashed a new expectation: that our program incorporate a name given
279
- into that greeting. When given the name "`Alice`", that's who should be
280
- greeted instead of "`World`".
281
-
282
- (Re)open `src/main/kotlin/HelloWorld.kt`.
283
-
284
- ```kotlin
285
- fun hello(name: String = ""): String {
286
- return "Hello, World!"
287
- }
288
- ```
289
-
290
- While `hello()` does accept a reference to a string named `name`, it is not
291
- using it in the output. Let's change that:
292
-
293
-
294
- ```kotlin
295
- fun hello(name: String = ""): String {
296
- return "Hello, $name!"
297
- }
298
- ```
299
-
300
- _(Kotlin allows you to embed expressions within strings, a feature known as
301
- string interpolation. For more about this feature, see
302
- https://kotlinlang.org/docs/reference/basic-types.html#string-templates )_
303
-
304
- ... and rerun the tests ...
305
-
306
- ```
307
- $ gradle test
308
- :test
309
-
310
- HelloWorldTest > helloSampleName PASSED
311
-
312
- HelloWorldTest > helloBlankName SKIPPED
313
-
314
- HelloWorldTest > helloNoName FAILED
315
- org.junit.ComparisonFailure: expected:<Hello, [World]!> but was:<Hello, []!>
316
- at org.junit.Assert.assertEquals(Assert.java:115)
317
- at org.junit.Assert.assertEquals(Assert.java:144)
318
- at HelloWorldTest.helloNoName(HelloWorldTest.kt:10)
319
-
320
- HelloWorldTest > helloAnotherSampleName SKIPPED
321
-
322
- 4 tests completed, 1 failed, 2 skipped
323
- ```
324
-
325
- Wait... didn't we just fix the test? Why is it failing? Take a closer look...
326
-
327
- In fact, `helloSampleName()` *is* passing. It's just that at the same time,
328
- we just inadvertently broke that first test: `helloNoName()`.
329
-
330
- This is one tiny example of the benefit of maintaining a test suite: if we
331
- use them to drive out our code, the second we break the program the tests
332
- say so. Since we saw them passing just *before* our latest change,
333
- whatever we *just* did most likely cause that regression.
334
-
335
- Our latest change was making the greeting dependent on the name given. If
336
- no name is given, our function defaults to an empty string. The intent is
337
- that when `hello()` is called on no one in particular, our function greets
338
- the whole world. Sound like a job for a default value!
339
-
340
- `src/main/kotlin/HelloWorld.kt`:
341
- ```kotlin
342
- fun hello(name: String = "World"): String {
343
- return "Hello, $name!"
344
- }
345
- ```
346
-
347
- ... and re-run the tests ...
348
-
349
- ```
350
- $ gradle test
351
- :compileKotlin
352
- :compileJava UP-TO-DATE
353
- :copyMainKotlinClasses
354
- :processResources UP-TO-DATE
355
- :classes UP-TO-DATE
356
- :compileTestKotlin
357
- :compileTestJava UP-TO-DATE
358
- :copyTestKotlinClasses
359
- :processTestResources UP-TO-DATE
360
- :testClasses UP-TO-DATE
361
- :test
362
-
363
- HelloWorldTest > helloSampleName PASSED
364
-
365
- HelloWorldTest > helloBlankName SKIPPED
366
-
367
- HelloWorldTest > helloNoName PASSED
368
-
369
- HelloWorldTest > helloAnotherSampleName SKIPPED
370
-
371
- BUILD SUCCESSFUL
372
- ```
373
-
374
- Excellent! Not only are both our tests passing, but that pesky warning
375
- about not using `name` has faded into the distant past. We're now
376
- (at least) three-fourth the way done. Just two more tests to go...
377
-
378
-
379
-
380
- ## Enabling and fixing the third test
381
-
382
- (Re)open `src/test/kotlin/HelloWorldTest.kt` and find the penultimate test:
383
-
384
- ```kotlin
385
- @Test
386
- @Ignore
387
- fun helloBlankName() {
388
- assertEquals("Hello, World!", hello(" "))
389
- }
390
- ```
391
-
392
- In this test, we're trying to be tricky. It's one thing to omit a
393
- parameter completely; it's a whole other situation when we provide a blank
394
- string for a name. This test is telling us that we'd like to treat these
395
- cases the same way.
396
-
397
- ... and remove it's `@Ignore` to enable it ...
398
-
399
- ```kotlin
400
- @Test
401
- fun helloBlankName() {
402
- assertEquals("Hello, World!", hello(" "))
403
- }
404
- ```
405
-
406
- ... and re-run the tests ...
407
-
408
- ```
409
- $ gradle test
410
- :test
411
-
412
- HelloWorldTest > helloSampleName PASSED
413
-
414
- HelloWorldTest > helloBlankName FAILED
415
- org.junit.ComparisonFailure: expected:<Hello, [World]!> but was:<Hello, [ ]!>
416
- at org.junit.Assert.assertEquals(Assert.java:115)
417
- at org.junit.Assert.assertEquals(Assert.java:144)
418
- at HelloWorldTest.helloBlankName(HelloWorldTest.kt:20)
419
-
420
- HelloWorldTest > helloNoName PASSED
421
-
422
- HelloWorldTest > helloAnotherSampleName SKIPPED
423
-
424
- 4 tests completed, 1 failed, 1 skipped
425
- ```
426
-
427
- Since `" "` is an actual value, Kotlin does _not_ substitute in the
428
- default value.
429
-
430
- (Re)open `src/main/kotlin/HelloWorld.kt`.
431
-
432
- ```kotlin
433
- fun hello(name: String = "World"): String {
434
- return "Hello, $name!"
435
- }
436
- ```
437
-
438
- One way to handle this case is to check to see if `name` is blank. Let's
439
- do that:
440
-
441
-
442
- ```kotlin
443
- fun hello(name: String = "World"): String {
444
- return "Hello, ${if (name.isBlank()) "World" else name}!"
445
- }
446
- ```
447
-
448
- As you can see, string templates can contain not just references to
449
- variables, but entire expressions! This is appropriate in a case like this
450
- where we want to apply a simple condition to a value.
451
-
452
- ... and rerun the tests ...
453
-
454
- ```
455
- $ gradle test
456
- :test
457
-
458
- HelloWorldTest > helloSampleName PASSED
459
-
460
- HelloWorldTest > helloBlankName PASSED
461
-
462
- HelloWorldTest > helloNoName PASSED
463
-
464
- HelloWorldTest > helloAnotherSampleName SKIPPED
465
-
466
- BUILD SUCCESSFUL
467
- ```
468
-
469
- We're almost there (perhaps closer than you think)! Just _one_ more test
470
- to pass before we have a solution we can have real confidence in.
471
-
472
-
473
-
474
- ## Enabling the last test
475
-
476
- (Re)open `src/test/kotlin/HelloWorldTest.kt` and find the last test:
477
-
478
- ```kotlin
479
- @Test
480
- @Ignore
481
- fun helloAnotherSampleName() {
482
- assertEquals("Hello, Bob!", hello("Bob"))
483
- }
484
- ```
485
-
486
- ... and pop-off that `@Ignore` ...
487
-
488
- ```kotlin
489
- @Test
490
- fun helloAnotherSampleName() {
491
- assertEquals("Hello, Bob!", hello("Bob"))
492
- }
493
- ```
494
-
495
- ... then rerun the tests ...
496
-
497
- ```
498
- :test
499
-
500
- HelloWorldTest > helloSampleName PASSED
501
-
502
- HelloWorldTest > helloBlankName PASSED
503
-
504
- HelloWorldTest > helloNoName PASSED
505
-
506
- HelloWorldTest > helloAnotherSampleName PASSED
507
-
508
- BUILD SUCCESSFUL
509
- ```
510
-
511
- Oh, hello! Turns out, the solution we put into place didn't just apply for
512
- "`Alice`" but for "`Bob`" equally well. In this case, the test succeeded
513
- with no additional code on our part.
514
-
515
205
  Congratulations!
516
206
 
517
-
518
-
519
- ## Refactoring
520
-
521
- Now that you've got all the tests passing, you might consider whether
522
- the code is in the most readable/maintainable/efficient shape. What makes
523
- for "good" design of software is a big topic. The pursuit of it underlies
524
- much of what makes up the more valuable conversations on Exercism.
525
-
526
- Kotlin is such a concise language and this exercise is so small, there is
527
- not much room for us to make adjustments. Most would leave this code, as
528
- is.
529
-
530
- That said, we've taken such pains to illustrate two core parts of the
531
- Test-Driven Development approach (i.e. "red", "green"), we'd be remiss if
532
- we skipped the all important final part: "refactor".
533
-
534
- More on TDD at http://www.jamesshore.com/Blog/Red-Green-Refactor.html.
535
-
536
- The core responsibility of `hello()` is to produce a personalized greeting.
537
- _How_ we determine whether or not a name is given (i.e. `name` is
538
- effectively an empty string) is a lower-level detail.
539
-
540
- ```kotlin
541
- fun hello(name: String = "World"): String {
542
- return "Hello, ${if (name.isBlank()) "World" else name}!"
543
- }
544
- ```
545
-
546
- How would things read if we extracted that detail into a separate method?
547
-
548
- ```kotlin
549
- fun hello(name: String = ""): String {
550
- return "Hello, ${whom(name)}!"
551
- }
552
-
553
- private fun whom(name: String):String {
554
- return if(name.isBlank()) "World" else name
555
- }
556
- ```
557
-
558
- By extracting that logic into the `whom()` method, we've added a little
559
- abstraction to our program — it's not as literal as it was before. Yet,
560
- it allows us to defer _needing_ to understand _how_ the recipient of the
561
- greeting is determined.
562
-
563
- If we can assume that `whom()` just works, we don't have to
564
- downshift in our head to those details. Instead, we can remain at the same
565
- level of thinking: what's the greeting?
566
-
567
- _(Yes, this is considerable more lines of code; again, not a move we'd likely
568
- make typically. The takeaway is this: when you are "done" with an exercise
569
- ask yourself, "can I adjust the shape of this code to better tell the
570
- story of what's going on through its shape?")_
571
-
572
- We made a bunch of changes, let's make sure we didn't break the program!
573
-
574
- ```
575
- $ gradle test
576
- :compileKotlin
577
- :compileJava UP-TO-DATE
578
- :copyMainKotlinClasses
579
- :processResources UP-TO-DATE
580
- :classes UP-TO-DATE
581
- :compileTestKotlin
582
- :compileTestJava UP-TO-DATE
583
- :copyTestKotlinClasses UP-TO-DATE
584
- :processTestResources UP-TO-DATE
585
- :testClasses UP-TO-DATE
586
- :test
587
-
588
- HelloWorldTest > helloSampleName PASSED
589
-
590
- HelloWorldTest > helloBlankName PASSED
591
-
592
- HelloWorldTest > helloNoName PASSED
593
-
594
- HelloWorldTest > helloAnotherSampleName PASSED
595
-
596
- BUILD SUCCESSFUL
597
- ```
598
-
599
- This illustrates another benefit of writing tests: you can make significant
600
- changes to the structure of the program and very quickly restore your
601
- confidence that the program still works. These tests are a far cry from a
602
- "proof" of correctness, but well-written tests do a much better job of
603
- (very quickly) giving us evidence that it is. Without them, we manually
604
- run the program with different inputs and/or inspecting the code
605
- line-by-line — time-consuming and error prone.
606
-
607
-
608
-
609
207
  # Submitting your first iteration
610
208
 
611
209
  With a working solution that we've reviewed, we're ready to submit it to