trackler 2.2.1.71 → 2.2.1.72

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/book-store/canonical-data.json +9 -2
  4. data/problem-specifications/exercises/word-count/canonical-data.json +9 -0
  5. data/tracks/bash/CONTRIBUTING.md +199 -0
  6. data/tracks/bash/config.json +24 -11
  7. data/tracks/bash/exercises/triangle/README.md +38 -0
  8. data/tracks/bash/exercises/triangle/example.sh +56 -0
  9. data/tracks/bash/exercises/triangle/triangle_test.sh +126 -0
  10. data/tracks/bash/img/canonical-data-example.png +0 -0
  11. data/tracks/bash/img/create-pr.png +0 -0
  12. data/tracks/bash/img/fork-repository.png +0 -0
  13. data/tracks/c/exercises/acronym/makefile +1 -1
  14. data/tracks/c/exercises/all-your-base/makefile +1 -1
  15. data/tracks/c/exercises/allergies/makefile +1 -1
  16. data/tracks/c/exercises/anagram/makefile +1 -1
  17. data/tracks/c/exercises/atbash-cipher/makefile +1 -1
  18. data/tracks/c/exercises/beer-song/makefile +1 -1
  19. data/tracks/c/exercises/binary-search/makefile +1 -1
  20. data/tracks/c/exercises/binary/makefile +1 -1
  21. data/tracks/c/exercises/bob/makefile +1 -1
  22. data/tracks/c/exercises/clock/makefile +1 -1
  23. data/tracks/c/exercises/collatz-conjecture/makefile +1 -1
  24. data/tracks/c/exercises/difference-of-squares/makefile +1 -1
  25. data/tracks/c/exercises/gigasecond/makefile +1 -1
  26. data/tracks/c/exercises/grains/makefile +1 -1
  27. data/tracks/c/exercises/hamming/makefile +1 -1
  28. data/tracks/c/exercises/hamming/test/test_hamming.c +2 -2
  29. data/tracks/c/exercises/hello-world/makefile +1 -1
  30. data/tracks/c/exercises/isogram/makefile +1 -1
  31. data/tracks/c/exercises/largest-series-product/makefile +1 -1
  32. data/tracks/c/exercises/leap/makefile +1 -1
  33. data/tracks/c/exercises/meetup/makefile +1 -1
  34. data/tracks/c/exercises/nth-prime/makefile +1 -1
  35. data/tracks/c/exercises/nucleotide-count/makefile +1 -1
  36. data/tracks/c/exercises/palindrome-products/makefile +1 -1
  37. data/tracks/c/exercises/pangram/makefile +1 -1
  38. data/tracks/c/exercises/pascals-triangle/makefile +1 -1
  39. data/tracks/c/exercises/perfect-numbers/makefile +1 -1
  40. data/tracks/c/exercises/phone-number/makefile +1 -1
  41. data/tracks/c/exercises/queen-attack/makefile +1 -1
  42. data/tracks/c/exercises/raindrops/makefile +1 -1
  43. data/tracks/c/exercises/react/makefile +1 -1
  44. data/tracks/c/exercises/rna-transcription/makefile +1 -1
  45. data/tracks/c/exercises/robot-simulator/makefile +1 -1
  46. data/tracks/c/exercises/roman-numerals/makefile +1 -1
  47. data/tracks/c/exercises/scrabble-score/makefile +1 -1
  48. data/tracks/c/exercises/series/makefile +1 -1
  49. data/tracks/c/exercises/sieve/makefile +1 -1
  50. data/tracks/c/exercises/space-age/makefile +1 -1
  51. data/tracks/c/exercises/sublist/makefile +1 -1
  52. data/tracks/c/exercises/sum-of-multiples/makefile +1 -1
  53. data/tracks/c/exercises/triangle/makefile +1 -1
  54. data/tracks/c/exercises/word-count/makefile +1 -1
  55. data/tracks/delphi/exercises/allergies/README.md +1 -1
  56. data/tracks/delphi/exercises/bank-account/README.md +1 -1
  57. data/tracks/delphi/exercises/beer-song/README.md +1 -1
  58. data/tracks/delphi/exercises/binary-search/README.md +1 -1
  59. data/tracks/delphi/exercises/bob/README.md +1 -1
  60. data/tracks/delphi/exercises/book-store/README.md +1 -1
  61. data/tracks/delphi/exercises/book-store/uBookStoreExample.pas +34 -14
  62. data/tracks/delphi/exercises/book-store/uBookStoreTests.pas +36 -1
  63. data/tracks/delphi/exercises/bowling/README.md +1 -1
  64. data/tracks/delphi/exercises/circular-buffer/README.md +1 -1
  65. data/tracks/delphi/exercises/clock/README.md +1 -1
  66. data/tracks/delphi/exercises/collatz-conjecture/README.md +1 -1
  67. data/tracks/delphi/exercises/etl/README.md +1 -1
  68. data/tracks/delphi/exercises/grains/README.md +1 -1
  69. data/tracks/delphi/exercises/hamming/README.md +1 -1
  70. data/tracks/delphi/exercises/hello-world/README.md +1 -1
  71. data/tracks/delphi/exercises/leap/README.md +1 -1
  72. data/tracks/delphi/exercises/minesweeper/README.md +1 -1
  73. data/tracks/delphi/exercises/nucleotide-count/README.md +1 -1
  74. data/tracks/delphi/exercises/perfect-numbers/README.md +1 -1
  75. data/tracks/delphi/exercises/phone-number/README.md +1 -1
  76. data/tracks/delphi/exercises/pig-latin/README.md +1 -1
  77. data/tracks/delphi/exercises/poker/README.md +1 -1
  78. data/tracks/delphi/exercises/raindrops/README.md +1 -1
  79. data/tracks/delphi/exercises/reverse-string/README.md +1 -1
  80. data/tracks/delphi/exercises/rna-transcription/README.md +1 -1
  81. data/tracks/delphi/exercises/roman-numerals/README.md +1 -1
  82. data/tracks/delphi/exercises/saddle-points/README.md +1 -1
  83. data/tracks/delphi/exercises/triangle/README.md +1 -1
  84. data/tracks/delphi/exercises/two-fer/README.md +1 -1
  85. data/tracks/delphi/exercises/wordy/README.md +1 -1
  86. data/tracks/ecmascript/.travis.yml +1 -1
  87. data/tracks/ecmascript/Makefile +4 -5
  88. data/tracks/ecmascript/README.md +2 -1
  89. data/tracks/ecmascript/config.json +12 -0
  90. data/tracks/ecmascript/exercises/change/package.json +5 -3
  91. data/tracks/ecmascript/exercises/protein-translation/package.json +2 -2
  92. data/tracks/ecmascript/exercises/react/README.md +41 -0
  93. data/tracks/ecmascript/exercises/react/example.js +101 -0
  94. data/tracks/ecmascript/exercises/react/package.json +71 -0
  95. data/tracks/ecmascript/exercises/react/react.spec.js +211 -0
  96. data/tracks/ecmascript/exercises/rectangles/package.json +1 -2
  97. data/tracks/ecmascript/exercises/rotational-cipher/package.json +1 -2
  98. data/tracks/ecmascript/exercises/spiral-matrix/package.json +1 -2
  99. data/tracks/ecmascript/exercises/transpose/package.json +2 -2
  100. data/tracks/erlang/docs/ABOUT.md +1 -1
  101. data/tracks/go/exercises/binary-search/.meta/gen.go +55 -0
  102. data/tracks/go/exercises/binary-search/binary_search_test.go +26 -167
  103. data/tracks/go/exercises/binary-search/cases_test.go +73 -0
  104. data/tracks/go/exercises/binary-search/example.go +8 -30
  105. data/tracks/go/exercises/nth-prime/.meta/gen.go +76 -0
  106. data/tracks/go/exercises/nth-prime/cases_test.go +43 -0
  107. data/tracks/go/exercises/nth-prime/nth_prime_test.go +4 -18
  108. data/tracks/go/exercises/prime-factors/.meta/gen.go +54 -0
  109. data/tracks/go/exercises/prime-factors/cases_test.go +48 -0
  110. data/tracks/go/exercises/prime-factors/prime_factors_test.go +4 -19
  111. data/tracks/groovy/config.json +13 -1
  112. data/tracks/groovy/exercises/linked-list/DoubleLinkedList.groovy +19 -0
  113. data/tracks/groovy/exercises/linked-list/DoubleLinkedListSpec.groovy +79 -0
  114. data/tracks/groovy/exercises/linked-list/Example.groovy +57 -0
  115. data/tracks/groovy/exercises/linked-list/README.md +49 -0
  116. data/tracks/java/bin/run-journey-test-from-ci.sh +1 -1
  117. data/tracks/java/config.json +10 -0
  118. data/tracks/java/config/maintainers.json +8 -1
  119. data/tracks/java/docs/MAINTAINING.md +3 -3
  120. data/tracks/java/exercises/accumulate/.meta/src/reference/java/Accumulate.java +2 -2
  121. data/tracks/java/exercises/binary/.meta/src/reference/java/Binary.java +3 -3
  122. data/tracks/java/exercises/circular-buffer/.meta/src/reference/java/BufferIOException.java +1 -1
  123. data/tracks/java/exercises/circular-buffer/.meta/src/reference/java/CircularBuffer.java +6 -6
  124. data/tracks/java/exercises/circular-buffer/src/main/java/BufferIOException.java +1 -1
  125. data/tracks/java/exercises/clock/.meta/src/reference/java/Clock.java +3 -3
  126. data/tracks/java/exercises/crypto-square/.meta/src/reference/java/Crypto.java +7 -7
  127. data/tracks/java/exercises/etl/.meta/src/reference/java/Etl.java +2 -2
  128. data/tracks/java/exercises/etl/src/main/java/Etl.java +2 -2
  129. data/tracks/java/exercises/kindergarten-garden/.meta/src/reference/java/KindergartenGarden.java +4 -4
  130. data/tracks/java/exercises/kindergarten-garden/.meta/src/reference/java/Plant.java +2 -2
  131. data/tracks/java/exercises/kindergarten-garden/src/main/java/Plant.java +2 -2
  132. data/tracks/java/exercises/nth-prime/.meta/src/reference/java/PrimeCalculator.java +2 -2
  133. data/tracks/java/exercises/reverse-string/.meta/src/reference/java/ReverseString.java +7 -0
  134. data/tracks/java/exercises/reverse-string/.meta/version +1 -0
  135. data/tracks/java/exercises/reverse-string/README.md +25 -0
  136. data/tracks/java/exercises/reverse-string/build.gradle +17 -0
  137. data/tracks/java/exercises/reverse-string/src/main/java/ReverseString.java +7 -0
  138. data/tracks/java/exercises/reverse-string/src/test/java/ReverseStringTest.java +37 -0
  139. data/tracks/java/exercises/run-length-encoding/.meta/src/reference/java/RunLengthEncoding.java +4 -4
  140. data/tracks/java/exercises/settings.gradle +1 -0
  141. data/tracks/kotlin/docs/RESOURCES.md +1 -1
  142. data/tracks/kotlin/exercises/accumulate/build.gradle +1 -1
  143. data/tracks/kotlin/exercises/acronym/build.gradle +1 -1
  144. data/tracks/kotlin/exercises/all-your-base/build.gradle +1 -1
  145. data/tracks/kotlin/exercises/allergies/build.gradle +1 -1
  146. data/tracks/kotlin/exercises/anagram/build.gradle +1 -1
  147. data/tracks/kotlin/exercises/atbash-cipher/build.gradle +1 -1
  148. data/tracks/kotlin/exercises/bank-account/build.gradle +1 -1
  149. data/tracks/kotlin/exercises/beer-song/build.gradle +1 -1
  150. data/tracks/kotlin/exercises/binary-search/build.gradle +1 -1
  151. data/tracks/kotlin/exercises/binary/build.gradle +1 -1
  152. data/tracks/kotlin/exercises/bob/build.gradle +1 -1
  153. data/tracks/kotlin/exercises/bracket-push/build.gradle +1 -1
  154. data/tracks/kotlin/exercises/change/build.gradle +1 -1
  155. data/tracks/kotlin/exercises/clock/build.gradle +1 -1
  156. data/tracks/kotlin/exercises/collatz-conjecture/build.gradle +1 -1
  157. data/tracks/kotlin/exercises/complex-numbers/build.gradle +1 -1
  158. data/tracks/kotlin/exercises/diamond/build.gradle +1 -1
  159. data/tracks/kotlin/exercises/difference-of-squares/build.gradle +1 -1
  160. data/tracks/kotlin/exercises/etl/build.gradle +1 -1
  161. data/tracks/kotlin/exercises/flatten-array/build.gradle +1 -1
  162. data/tracks/kotlin/exercises/forth/build.gradle +1 -1
  163. data/tracks/kotlin/exercises/gigasecond/build.gradle +1 -1
  164. data/tracks/kotlin/exercises/grade-school/build.gradle +1 -1
  165. data/tracks/kotlin/exercises/grains/build.gradle +1 -1
  166. data/tracks/kotlin/exercises/hamming/build.gradle +1 -1
  167. data/tracks/kotlin/exercises/hello-world/build.gradle +1 -1
  168. data/tracks/kotlin/exercises/hexadecimal/build.gradle +1 -1
  169. data/tracks/kotlin/exercises/isogram/build.gradle +1 -1
  170. data/tracks/kotlin/exercises/largest-series-product/build.gradle +1 -1
  171. data/tracks/kotlin/exercises/leap/build.gradle +1 -1
  172. data/tracks/kotlin/exercises/linked-list/build.gradle +1 -1
  173. data/tracks/kotlin/exercises/list-ops/build.gradle +1 -1
  174. data/tracks/kotlin/exercises/luhn/build.gradle +1 -1
  175. data/tracks/kotlin/exercises/meetup/build.gradle +1 -1
  176. data/tracks/kotlin/exercises/minesweeper/build.gradle +1 -1
  177. data/tracks/kotlin/exercises/nth-prime/build.gradle +1 -1
  178. data/tracks/kotlin/exercises/nucleotide-count/build.gradle +1 -1
  179. data/tracks/kotlin/exercises/pangram/build.gradle +1 -1
  180. data/tracks/kotlin/exercises/pascals-triangle/build.gradle +1 -1
  181. data/tracks/kotlin/exercises/perfect-numbers/build.gradle +1 -1
  182. data/tracks/kotlin/exercises/phone-number/build.gradle +1 -1
  183. data/tracks/kotlin/exercises/pig-latin/build.gradle +1 -1
  184. data/tracks/kotlin/exercises/prime-factors/build.gradle +1 -1
  185. data/tracks/kotlin/exercises/raindrops/build.gradle +1 -1
  186. data/tracks/kotlin/exercises/react/build.gradle +1 -1
  187. data/tracks/kotlin/exercises/rna-transcription/build.gradle +1 -1
  188. data/tracks/kotlin/exercises/robot-name/build.gradle +1 -1
  189. data/tracks/kotlin/exercises/robot-simulator/build.gradle +1 -1
  190. data/tracks/kotlin/exercises/roman-numerals/build.gradle +1 -1
  191. data/tracks/kotlin/exercises/rotational-cipher/build.gradle +1 -1
  192. data/tracks/kotlin/exercises/saddle-points/build.gradle +1 -1
  193. data/tracks/kotlin/exercises/say/build.gradle +1 -1
  194. data/tracks/kotlin/exercises/scrabble-score/build.gradle +1 -1
  195. data/tracks/kotlin/exercises/secret-handshake/build.gradle +1 -1
  196. data/tracks/kotlin/exercises/series/build.gradle +1 -1
  197. data/tracks/kotlin/exercises/sieve/build.gradle +1 -1
  198. data/tracks/kotlin/exercises/simple-cipher/README.md +4 -6
  199. data/tracks/kotlin/exercises/simple-cipher/build.gradle +1 -1
  200. data/tracks/kotlin/exercises/space-age/build.gradle +1 -1
  201. data/tracks/kotlin/exercises/spiral-matrix/build.gradle +1 -1
  202. data/tracks/kotlin/exercises/strain/build.gradle +1 -1
  203. data/tracks/kotlin/exercises/sublist/build.gradle +1 -1
  204. data/tracks/kotlin/exercises/sum-of-multiples/build.gradle +1 -1
  205. data/tracks/kotlin/exercises/triangle/build.gradle +1 -1
  206. data/tracks/kotlin/exercises/two-fer/build.gradle +1 -1
  207. data/tracks/kotlin/exercises/word-count/build.gradle +1 -1
  208. data/tracks/lua/.gitignore +1 -0
  209. data/tracks/lua/config.json +12 -0
  210. data/tracks/lua/exercises/isbn-verifier/README.md +52 -0
  211. data/tracks/lua/exercises/isbn-verifier/example.lua +16 -0
  212. data/tracks/lua/exercises/isbn-verifier/isbn-verifier_spec.lua +55 -0
  213. data/tracks/ocaml/.travis-ci.sh +1 -1
  214. data/tracks/ocaml/.travis.yml +1 -1
  215. data/tracks/ocaml/README.md +1 -1
  216. data/tracks/perl6/config.json +10 -0
  217. data/tracks/perl6/exercises/acronym/Acronym.pm6 +4 -0
  218. data/tracks/perl6/exercises/acronym/Example.pm6 +5 -0
  219. data/tracks/perl6/exercises/acronym/README.md +33 -0
  220. data/tracks/perl6/exercises/acronym/acronym.t +96 -0
  221. data/tracks/perl6/exercises/acronym/example.yaml +19 -0
  222. data/tracks/perl6/exercises/word-count/Example.pm6 +1 -1
  223. data/tracks/perl6/exercises/word-count/WordCount.pm6 +1 -1
  224. data/tracks/perl6/exercises/word-count/example.yaml +2 -2
  225. data/tracks/perl6/exercises/word-count/word-count.t +11 -2
  226. data/tracks/pony/docs/RESOURCES.md +1 -1
  227. data/tracks/purescript/docs/INSTALLATION.md +1 -3
  228. data/tracks/python/config.json +1 -1
  229. data/tracks/r/exercises/word-count/test_word-count.R +5 -0
  230. data/tracks/ruby/README.md +73 -10
  231. data/tracks/rust/config.json +34 -0
  232. data/tracks/rust/exercises/book-store/Cargo.toml +1 -1
  233. data/tracks/rust/exercises/book-store/tests/book-store.rs +7 -0
  234. data/tracks/rust/exercises/diffie-hellman/.gitignore +9 -0
  235. data/tracks/rust/exercises/diffie-hellman/Cargo-example.toml +6 -0
  236. data/tracks/rust/exercises/diffie-hellman/Cargo.toml +5 -0
  237. data/tracks/rust/exercises/diffie-hellman/README.md +77 -0
  238. data/tracks/rust/exercises/diffie-hellman/example.rs +15 -0
  239. data/tracks/rust/exercises/diffie-hellman/src/lib.rs +11 -0
  240. data/tracks/rust/exercises/diffie-hellman/tests/diffie-hellman.rs +60 -0
  241. data/tracks/rust/exercises/macros/.gitignore +3 -0
  242. data/tracks/rust/exercises/macros/.meta/description.md +29 -0
  243. data/tracks/rust/exercises/macros/.meta/metadata.yml +3 -0
  244. data/tracks/rust/exercises/macros/Cargo.toml +6 -0
  245. data/tracks/rust/exercises/macros/README.md +70 -0
  246. data/tracks/rust/exercises/macros/example.rs +16 -0
  247. data/tracks/rust/exercises/macros/src/lib.rs +6 -0
  248. data/tracks/rust/exercises/macros/tests/macros.rs +62 -0
  249. data/tracks/rust/exercises/simple-linked-list/.gitignore +7 -0
  250. data/tracks/rust/exercises/simple-linked-list/.meta/hints.md +34 -0
  251. data/tracks/rust/exercises/simple-linked-list/Cargo.toml +5 -0
  252. data/tracks/rust/exercises/simple-linked-list/README.md +96 -0
  253. data/tracks/rust/exercises/simple-linked-list/example.rs +87 -0
  254. data/tracks/rust/exercises/simple-linked-list/src/lib.rs +46 -0
  255. data/tracks/rust/exercises/simple-linked-list/tests/simple-linked-list.rs +91 -0
  256. data/tracks/swift/.travis.yml +1 -1
  257. data/tracks/swift/config.json +24 -0
  258. data/tracks/swift/exercises/isbn-verifier/Package.swift +5 -0
  259. data/tracks/swift/exercises/isbn-verifier/README.md +39 -0
  260. data/tracks/swift/exercises/isbn-verifier/Sources/IsbnVerifier.swift +1 -0
  261. data/tracks/swift/exercises/isbn-verifier/Sources/IsbnVerifierExample.swift +35 -0
  262. data/tracks/swift/exercises/isbn-verifier/Tests/IsbnVerifierTests/IsbnVerifierTests.swift +75 -0
  263. data/tracks/swift/exercises/isbn-verifier/Tests/LinuxMain.swift +6 -0
  264. data/tracks/swift/exercises/two-fer/Package.swift +5 -0
  265. data/tracks/swift/exercises/two-fer/README.md +54 -0
  266. data/tracks/swift/exercises/two-fer/Sources/TwoFer.swift +1 -0
  267. data/tracks/swift/exercises/two-fer/Sources/TwoFerExample.swift +6 -0
  268. data/tracks/swift/exercises/two-fer/Tests/LinuxMain.swift +6 -0
  269. data/tracks/swift/exercises/two-fer/Tests/TwoFerTests/TwoFerTests.swift +25 -0
  270. metadata +71 -2
@@ -0,0 +1,3 @@
1
+ # Ignore Cargo.lock if creating a library
2
+ # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
3
+ Cargo.lock
@@ -0,0 +1,29 @@
1
+ Macros are a powerful part of a Rust programmer's toolkit, and [macros by example](https://doc.rust-lang.org/reference/macros-by-example.html) are a relatively simple way to access this power. Let's write one!
2
+
3
+ ## Context
4
+
5
+ What is a macro? [Wikipedia](https://en.wikipedia.org/wiki/Macro_(computer_science)) describes it thus:
6
+
7
+ > A macro (short for "macroinstruction", from Greek μακρός 'long') in computer science is a rule or pattern that specifies how a certain input sequence (often a sequence of characters) should be mapped to a replacement output sequence (also often a sequence of characters) according to a defined procedure. The mapping process that instantiates (transforms) a macro use into a specific sequence is known as macro expansion.
8
+
9
+ Illuminating! But to be more concrete, macros are a special syntax which allows you to generate code at compile time. Macros can be used compile-time calculation, but more often they're just another way to abstract your code. For example, you've probably already used `println!()` and `vec![]`. These each take an arbitrary number of arguments, so you can't express them as simple functions. On the other hand, they always expand to some amount of absolutely standard Rust code. If you're interested, you can use the [cargo expand](https://github.com/dtolnay/cargo-expand) subcommand to view the results of macro expansion in your code.
10
+
11
+ For further information about macros in Rust, The Rust Book has a [good chapter](https://doc.rust-lang.org/book/first-edition/macros.html) on them.
12
+
13
+ ## Problem Statement
14
+
15
+ You can produce a `Vec` of arbitrary length inline by using the `vec![]` macro. However, Rust doesn't come with a way to produce a [`HashMap`](https://doc.rust-lang.org/std/collections/struct.HashMap.html) inline. Rectify this by writing a `hashmap!()` macro.
16
+
17
+ For example, a user of your library might write `hashmap!('a' => 3, 'b' => 11, 'z' => 32)`. This should expand to the following code:
18
+
19
+ ```rust
20
+ {
21
+ let mut hm = HashMap::new();
22
+ hm.insert('a', 3);
23
+ hm.insert('b', 11);
24
+ hm.insert('z', 32);
25
+ hm
26
+ }
27
+ ```
28
+
29
+ Note that the [`maplit` crate](https://crates.io/crates/maplit) provides a macro which perfectly solves this exercise. Please implement your own solution instead of using this crate; please make an attempt on your own before viewing its source.
@@ -0,0 +1,3 @@
1
+ ---
2
+ blurb: "Implement a macro using macros-by-example"
3
+ source: "Peter Goodspeed-Niklaus"
@@ -0,0 +1,6 @@
1
+ [package]
2
+ name = "macros"
3
+ version = "0.1.0"
4
+ authors = ["Peter Goodspeed-Niklaus <peter.r.goodspeedniklaus@gmail.com>"]
5
+
6
+ [dependencies]
@@ -0,0 +1,70 @@
1
+ # Macros
2
+
3
+ Macros are a powerful part of a Rust programmer's toolkit, and [macros by example](https://doc.rust-lang.org/reference/macros-by-example.html) are a relatively simple way to access this power. Let's write one!
4
+
5
+ ## Context
6
+
7
+ What is a macro? [Wikipedia](https://en.wikipedia.org/wiki/Macro_(computer_science)) describes it thus:
8
+
9
+ > A macro (short for "macroinstruction", from Greek μακρός 'long') in computer science is a rule or pattern that specifies how a certain input sequence (often a sequence of characters) should be mapped to a replacement output sequence (also often a sequence of characters) according to a defined procedure. The mapping process that instantiates (transforms) a macro use into a specific sequence is known as macro expansion.
10
+
11
+ Illuminating! But to be more concrete, macros are a special syntax which allows you to generate code at compile time. Macros can be used compile-time calculation, but more often they're just another way to abstract your code. For example, you've probably already used `println!()` and `vec![]`. These each take an arbitrary number of arguments, so you can't express them as simple functions. On the other hand, they always expand to some amount of absolutely standard Rust code. If you're interested, you can use the [cargo expand](https://github.com/dtolnay/cargo-expand) subcommand to view the results of macro expansion in your code.
12
+
13
+ For further information about macros in Rust, The Rust Book has a [good chapter](https://doc.rust-lang.org/book/first-edition/macros.html) on them.
14
+
15
+ ## Problem Statement
16
+
17
+ You can produce a `Vec` of arbitrary length inline by using the `vec![]` macro. However, Rust doesn't come with a way to produce a [`HashMap`](https://doc.rust-lang.org/std/collections/struct.HashMap.html) inline. Rectify this by writing a `hashmap!()` macro.
18
+
19
+ For example, a user of your library might write `hashmap!('a' => 3, 'b' => 11, 'z' => 32)`. This should expand to the following code:
20
+
21
+ ```rust
22
+ {
23
+ let mut hm = HashMap::new();
24
+ hm.insert('a', 3);
25
+ hm.insert('b', 11);
26
+ hm.insert('z', 32);
27
+ hm
28
+ }
29
+ ```
30
+
31
+ Note that the [`maplit` crate](https://crates.io/crates/maplit) provides a macro which perfectly solves this exercise. Please implement your own solution instead of using this crate; please make an attempt on your own before viewing its source.
32
+
33
+ ## Rust Installation
34
+
35
+ Refer to the [exercism help page][help-page] for Rust installation and learning
36
+ resources.
37
+
38
+ ## Writing the Code
39
+
40
+ Execute the tests with:
41
+
42
+ ```bash
43
+ $ cargo test
44
+ ```
45
+
46
+ All but the first test have been ignored. After you get the first test to
47
+ pass, remove the ignore flag (`#[ignore]`) from the next test and get the tests
48
+ to pass again. The test file is located in the `tests` directory. You can
49
+ also remove the ignore flag from all the tests to get them to run all at once
50
+ if you wish.
51
+
52
+ Make sure to read the [Modules](https://doc.rust-lang.org/book/second-edition/ch07-00-modules.html) chapter if you
53
+ haven't already, it will help you with organizing your files.
54
+
55
+ ## Feedback, Issues, Pull Requests
56
+
57
+ The [exercism/rust](https://github.com/exercism/rust) repository on GitHub is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the [rust track team](https://github.com/orgs/exercism/teams/rust) are happy to help!
58
+
59
+ If you want to know more about Exercism, take a look at the [contribution guide](https://github.com/exercism/docs/blob/master/contributing-to-language-tracks/README.md).
60
+
61
+ [help-page]: http://exercism.io/languages/rust
62
+ [modules]: https://doc.rust-lang.org/book/second-edition/ch07-00-modules.html
63
+ [cargo]: https://doc.rust-lang.org/book/second-edition/ch14-00-more-about-cargo.html
64
+
65
+ ## Source
66
+
67
+ Peter Goodspeed-Niklaus
68
+
69
+ ## Submitting Incomplete Solutions
70
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,16 @@
1
+ // Ignoring the README's injunction, this is heavily based on the implementation from maplit.
2
+ // Original source is at https://github.com/bluss/maplit/blob/master/src/lib.rs#L27-L60
3
+
4
+ #[macro_export]
5
+ macro_rules! hashmap {
6
+ ($($key:expr => $value:expr,)+) => { hashmap!($($key => $value),+) };
7
+ ($($key:expr => $value:expr),*) => {
8
+ {
9
+ let mut _map = ::std::collections::HashMap::new();
10
+ $(
11
+ _map.insert($key, $value);
12
+ )*
13
+ _map
14
+ }
15
+ };
16
+ }
@@ -0,0 +1,6 @@
1
+ #[macro_export]
2
+ macro_rules! hashmap {
3
+ () => {
4
+ unimplemented!()
5
+ };
6
+ }
@@ -0,0 +1,62 @@
1
+ #[macro_use]
2
+ extern crate macros;
3
+
4
+ use std::collections::HashMap;
5
+
6
+ #[test]
7
+ fn test_empty() {
8
+ let expected: HashMap<usize, usize> = HashMap::new();
9
+ let computed: HashMap<usize, usize> = hashmap!();
10
+ assert_eq!(computed, expected);
11
+ }
12
+
13
+ #[test]
14
+ #[ignore]
15
+ fn test_no_trailing_comma() {
16
+ let mut expected = HashMap::new();
17
+ expected.insert(1, "one");
18
+ expected.insert(2, "two");
19
+ assert_eq!(hashmap!(1 => "one", 2 => "two"), expected);
20
+ }
21
+
22
+ #[test]
23
+ #[ignore]
24
+ fn test_trailing_comma() {
25
+ let mut expected = HashMap::new();
26
+ expected.insert('h', 89);
27
+ expected.insert('a', 1);
28
+ expected.insert('s', 19);
29
+ expected.insert('h', 8);
30
+ assert_eq!(
31
+ hashmap!(
32
+ 'h' => 89,
33
+ 'a' => 1,
34
+ 's' => 19,
35
+ 'h' => 8,
36
+ ),
37
+ expected
38
+ );
39
+ }
40
+
41
+ #[test]
42
+ #[ignore]
43
+ fn test_nested() {
44
+ let mut expected = HashMap::new();
45
+ expected.insert("non-empty", {
46
+ let mut subhashmap = HashMap::new();
47
+ subhashmap.insert(23, 623);
48
+ subhashmap.insert(34, 21);
49
+ subhashmap
50
+ });
51
+ expected.insert("empty", HashMap::new());
52
+ assert_eq!(
53
+ hashmap!(
54
+ "non-empty" => hashmap!(
55
+ 23 => 623,
56
+ 34 => 21
57
+ ),
58
+ "empty" => hashmap!()
59
+ ),
60
+ expected
61
+ );
62
+ }
@@ -0,0 +1,7 @@
1
+ # Generated by Cargo
2
+ # will have compiled files and executables
3
+ /target/
4
+
5
+ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6
+ # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
7
+ Cargo.lock
@@ -0,0 +1,34 @@
1
+ ## Implementation Hints
2
+
3
+ Do not implement the struct `SimpleLinkedList` as a wrapper around a `Vec`. Instead, allocate nodes on the heap.
4
+ This might be implemented as:
5
+ ```
6
+ pub struct SimpleLinkedList<T> {
7
+ head: Option<Box<Node<T>>>,
8
+ }
9
+ ```
10
+ The `head` field points to the first element (Node) of this linked list.
11
+ This implementation also requires a struct `Node` with the following fields:
12
+ ```
13
+ struct Node<T> {
14
+ data: T,
15
+ next: Option<Box<Node<T>>>,
16
+ }
17
+ ```
18
+ `data` contains the stored data, and `next` points to the following node (if available) or None.
19
+
20
+ ### Why Option<__Box__<Node<T>>> and not just Option<Node<T>>?
21
+ Try it on your own. You will get the following error.
22
+
23
+ ```
24
+ | struct Node<T>
25
+ | ^^^^^^^^^^^^^^ recursive type has infinite size
26
+ ...
27
+ | next: Option<Node<T>>,
28
+ | --------------------- recursive without indirection
29
+ ```
30
+
31
+ The problem is that at compile time the size of next must be known.
32
+ Since `next` is recursive ("a node has a node has a node..."), the compiler does not know how much memory is to be allocated.
33
+ In contrast, [Box](https://doc.rust-lang.org/std/boxed/) is a heap pointer with a defined size.
34
+
@@ -0,0 +1,5 @@
1
+ [package]
2
+ name = "simple_linked_list"
3
+ version = "0.1.0"
4
+
5
+ [dependencies]
@@ -0,0 +1,96 @@
1
+ # Simple Linked List
2
+
3
+ Write a simple linked list implementation that uses Elements and a List.
4
+
5
+ The linked list is a fundamental data structure in computer science,
6
+ often used in the implementation of other data structures. They're
7
+ pervasive in functional programming languages, such as Clojure, Erlang,
8
+ or Haskell, but far less common in imperative languages such as Ruby or
9
+ Python.
10
+
11
+ The simplest kind of linked list is a singly linked list. Each element in the
12
+ list contains data and a "next" field pointing to the next element in the list
13
+ of elements.
14
+
15
+ This variant of linked lists is often used to represent sequences or
16
+ push-down stacks (also called a LIFO stack; Last In, First Out).
17
+
18
+ As a first take, lets create a singly linked list to contain the range (1..10),
19
+ and provide functions to reverse a linked list and convert to and from arrays.
20
+
21
+ When implementing this in a language with built-in linked lists,
22
+ implement your own abstract data type.
23
+
24
+ ## Implementation Hints
25
+
26
+ Do not implement the struct `SimpleLinkedList` as a wrapper around a `Vec`. Instead, allocate nodes on the heap.
27
+ This might be implemented as:
28
+ ```
29
+ pub struct SimpleLinkedList<T> {
30
+ head: Option<Box<Node<T>>>,
31
+ }
32
+ ```
33
+ The `head` field points to the first element (Node) of this linked list.
34
+ This implementation also requires a struct `Node` with the following fields:
35
+ ```
36
+ struct Node<T> {
37
+ data: T,
38
+ next: Option<Box<Node<T>>>,
39
+ }
40
+ ```
41
+ `data` contains the stored data, and `next` points to the following node (if available) or None.
42
+
43
+ ### Why Option<__Box__<Node<T>>> and not just Option<Node<T>>?
44
+ Try it on your own. You will get the following error.
45
+
46
+ ```
47
+ | struct Node<T>
48
+ | ^^^^^^^^^^^^^^ recursive type has infinite size
49
+ ...
50
+ | next: Option<Node<T>>,
51
+ | --------------------- recursive without indirection
52
+ ```
53
+
54
+ The problem is that at compile time the size of next must be known.
55
+ Since `next` is recursive ("a node has a node has a node..."), the compiler does not know how much memory is to be allocated.
56
+ In contrast, [Box](https://doc.rust-lang.org/std/boxed/) is a heap pointer with a defined size.
57
+
58
+
59
+ ## Rust Installation
60
+
61
+ Refer to the [exercism help page][help-page] for Rust installation and learning
62
+ resources.
63
+
64
+ ## Writing the Code
65
+
66
+ Execute the tests with:
67
+
68
+ ```bash
69
+ $ cargo test
70
+ ```
71
+
72
+ All but the first test have been ignored. After you get the first test to
73
+ pass, remove the ignore flag (`#[ignore]`) from the next test and get the tests
74
+ to pass again. The test file is located in the `tests` directory. You can
75
+ also remove the ignore flag from all the tests to get them to run all at once
76
+ if you wish.
77
+
78
+ Make sure to read the [Modules](https://doc.rust-lang.org/book/second-edition/ch07-00-modules.html) chapter if you
79
+ haven't already, it will help you with organizing your files.
80
+
81
+ ## Feedback, Issues, Pull Requests
82
+
83
+ The [exercism/rust](https://github.com/exercism/rust) repository on GitHub is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the [rust track team](https://github.com/orgs/exercism/teams/rust) are happy to help!
84
+
85
+ If you want to know more about Exercism, take a look at the [contribution guide](https://github.com/exercism/docs/blob/master/contributing-to-language-tracks/README.md).
86
+
87
+ [help-page]: http://exercism.io/languages/rust
88
+ [modules]: https://doc.rust-lang.org/book/second-edition/ch07-00-modules.html
89
+ [cargo]: https://doc.rust-lang.org/book/second-edition/ch14-00-more-about-cargo.html
90
+
91
+ ## Source
92
+
93
+ Inspired by 'Data Structures and Algorithms with Object-Oriented Design Patterns in Ruby', singly linked-lists. [http://www.brpreiss.com/books/opus8/html/page96.html#SECTION004300000000000000000](http://www.brpreiss.com/books/opus8/html/page96.html#SECTION004300000000000000000)
94
+
95
+ ## Submitting Incomplete Solutions
96
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,87 @@
1
+ pub struct SimpleLinkedList<T> {
2
+ head: Option<Box<Node<T>>>,
3
+ len: usize,
4
+ }
5
+
6
+ struct Node<T> {
7
+ data: T,
8
+ next: Option<Box<Node<T>>>,
9
+ }
10
+
11
+
12
+ impl<T> SimpleLinkedList<T> {
13
+ pub fn new() -> Self {
14
+ SimpleLinkedList { head: None, len: 0 }
15
+ }
16
+
17
+ pub fn len(&self) -> usize {
18
+ self.len
19
+ }
20
+
21
+ pub fn push(&mut self, element: T) {
22
+ let node = Box::new(Node::new(element, self.head.take()));
23
+ self.head = Some(node);
24
+ self.len += 1;
25
+ }
26
+
27
+ pub fn pop(&mut self) -> Option<T> {
28
+ match self.len {
29
+ 0 => None,
30
+ _ => {
31
+ self.len -= 1;
32
+ self.head.take().map(|node| {
33
+ let node = *node;
34
+ self.head = node.next;
35
+ node.data
36
+ })
37
+ }
38
+ }
39
+ }
40
+
41
+ pub fn peek(&self) -> Option<&T> {
42
+ self.head.as_ref().map(|node| &node.data)
43
+ }
44
+ }
45
+
46
+ impl<T: Clone> SimpleLinkedList<T> {
47
+ pub fn rev(&self) -> SimpleLinkedList<T> {
48
+ let mut rev_list = SimpleLinkedList::new();
49
+ let mut next = self.head.as_ref().map(|node| &**node);
50
+ while let Some(node) = next {
51
+ rev_list.push(node.data.clone());
52
+ next = node.next.as_ref().map(|node| &**node);
53
+ }
54
+ rev_list
55
+ }
56
+ }
57
+
58
+
59
+ impl<'a, T: Clone> From<&'a [T]> for SimpleLinkedList<T> {
60
+ fn from(item: &[T]) -> Self {
61
+ let mut list = SimpleLinkedList::new();
62
+ for i in item {
63
+ list.push(i.clone());
64
+ }
65
+ list
66
+ }
67
+ }
68
+
69
+ impl<T> Into<Vec<T>> for SimpleLinkedList<T> {
70
+ fn into(mut self) -> Vec<T> {
71
+ let mut vec = Vec::new();
72
+ while let Some(data) = self.pop() {
73
+ vec.push(data);
74
+ }
75
+ vec.reverse();
76
+ vec
77
+ }
78
+ }
79
+
80
+ impl<T> Node<T> {
81
+ pub fn new(element: T, next: Option<Box<Node<T>>>) -> Self {
82
+ Node {
83
+ data: element,
84
+ next,
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,46 @@
1
+ pub struct SimpleLinkedList<T> {
2
+ // Delete this field
3
+ // _dummy is needed to avoid unused parameter error during compilation
4
+ _dummy: T,
5
+ }
6
+
7
+ impl<T> SimpleLinkedList<T> {
8
+ pub fn new() -> Self {
9
+ unimplemented!()
10
+ }
11
+
12
+ pub fn len(&self) -> usize {
13
+ unimplemented!()
14
+ }
15
+
16
+ pub fn push(&mut self, element: T) {
17
+ unimplemented!()
18
+ }
19
+
20
+ pub fn pop(&mut self) -> Option<T> {
21
+ unimplemented!()
22
+ }
23
+
24
+ pub fn peek(&self) -> Option<&T> {
25
+ unimplemented!()
26
+ }
27
+ }
28
+
29
+ impl<T: Clone> SimpleLinkedList<T> {
30
+ pub fn rev(&self) -> SimpleLinkedList<T> {
31
+ unimplemented!()
32
+ }
33
+ }
34
+
35
+
36
+ impl<'a, T: Clone> From<&'a [T]> for SimpleLinkedList<T> {
37
+ fn from(item: &[T]) -> Self {
38
+ unimplemented!()
39
+ }
40
+ }
41
+
42
+ impl<T> Into<Vec<T>> for SimpleLinkedList<T> {
43
+ fn into(mut self) -> Vec<T> {
44
+ unimplemented!()
45
+ }
46
+ }