trackler 2.2.1.100 → 2.2.1.101

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/kindergarten-garden/canonical-data.json +37 -19
  4. data/problem-specifications/exercises/ocr-numbers/canonical-data.json +144 -110
  5. data/problem-specifications/exercises/palindrome-products/canonical-data.json +49 -25
  6. data/problem-specifications/exercises/poker/canonical-data.json +171 -115
  7. data/problem-specifications/exercises/prime-factors/canonical-data.json +22 -8
  8. data/problem-specifications/exercises/protein-translation/canonical-data.json +70 -24
  9. data/problem-specifications/exercises/proverb/canonical-data.json +24 -12
  10. data/problem-specifications/exercises/queen-attack/canonical-data.json +115 -91
  11. data/problem-specifications/exercises/rail-fence-cipher/canonical-data.json +25 -13
  12. data/problem-specifications/exercises/raindrops/canonical-data.json +55 -19
  13. data/problem-specifications/exercises/rational-numbers/canonical-data.json +374 -0
  14. data/problem-specifications/exercises/rational-numbers/description.md +27 -0
  15. data/problem-specifications/exercises/rational-numbers/metadata.yml +4 -0
  16. data/problem-specifications/exercises/rectangles/canonical-data.json +93 -67
  17. data/problem-specifications/exercises/reverse-string/canonical-data.json +16 -6
  18. data/problem-specifications/exercises/rna-transcription/metadata.yml +3 -3
  19. data/problem-specifications/exercises/roman-numerals/canonical-data.json +10 -2
  20. data/tracks/bash/config.json +11 -11
  21. data/tracks/c/exercises/roman-numerals/test/test_roman_numerals.c +7 -0
  22. data/tracks/clojure/exercises/armstrong-numbers/README.md +1 -1
  23. data/tracks/delphi/config.json +11 -0
  24. data/tracks/delphi/exercises/clock/uClockExample.pas +6 -1
  25. data/tracks/delphi/exercises/clock/uClockTest.pas +22 -19
  26. data/tracks/delphi/exercises/isbn-verifier/README.md +1 -1
  27. data/tracks/delphi/exercises/reverse-string/README.md +1 -1
  28. data/tracks/delphi/exercises/rna-transcription/README.md +1 -1
  29. data/tracks/delphi/exercises/roman-numerals/uRomanNumeralsTest.pas +14 -0
  30. data/tracks/delphi/exercises/space-age/README.md +45 -0
  31. data/tracks/delphi/exercises/space-age/SpaceAge.dpr +60 -0
  32. data/tracks/delphi/exercises/space-age/uSpaceAgeExample.pas +120 -0
  33. data/tracks/delphi/exercises/space-age/uSpaceAgeTests.pas +135 -0
  34. data/tracks/delphi/exercises/two-fer/README.md +1 -1
  35. data/tracks/elixir/exercises/nth-prime/nth_prime.exs +0 -1
  36. data/tracks/fsharp/exercises/pov/PovTest.fs +66 -53
  37. data/tracks/fsharp/exercises/space-age/Example.fs +11 -11
  38. data/tracks/fsharp/exercises/space-age/SpaceAge.fs +1 -1
  39. data/tracks/fsharp/exercises/space-age/SpaceAgeTest.fs +21 -34
  40. data/tracks/fsharp/exercises/triangle/Example.fs +11 -16
  41. data/tracks/fsharp/exercises/triangle/Triangle.fs +4 -5
  42. data/tracks/fsharp/exercises/triangle/TriangleTest.fs +44 -31
  43. data/tracks/fsharp/generators/Generators.fs +121 -0
  44. data/tracks/go/config.json +12 -0
  45. data/tracks/go/exercises/clock/.meta/gen.go +37 -13
  46. data/tracks/go/exercises/clock/cases_test.go +10 -10
  47. data/tracks/go/exercises/clock/clock_test.go +16 -2
  48. data/tracks/go/exercises/clock/example.go +4 -0
  49. data/tracks/go/exercises/clock/example_clock_test.go +3 -3
  50. data/tracks/go/exercises/parallel-letter-frequency/.meta/hints.md +33 -0
  51. data/tracks/go/exercises/parallel-letter-frequency/README.md +35 -0
  52. data/tracks/go/exercises/raindrops/.meta/hints.md +7 -4
  53. data/tracks/go/exercises/raindrops/README.md +12 -0
  54. data/tracks/go/exercises/roman-numerals/.meta/gen.go +4 -2
  55. data/tracks/go/exercises/roman-numerals/cases_test.go +3 -2
  56. data/tracks/go/exercises/space-age/.meta/hints.md +10 -0
  57. data/tracks/go/exercises/space-age/README.md +14 -1
  58. data/tracks/go/exercises/twelve-days/README.md +2 -5
  59. data/tracks/go/exercises/two-bucket/.meta/gen.go +62 -0
  60. data/tracks/go/exercises/two-bucket/.meta/hints.md +16 -0
  61. data/tracks/go/exercises/two-bucket/README.md +72 -0
  62. data/tracks/go/exercises/two-bucket/cases_test.go +44 -0
  63. data/tracks/go/exercises/two-bucket/example.go +198 -0
  64. data/tracks/go/exercises/two-bucket/two_bucket_test.go +61 -0
  65. data/tracks/idris/.travis.yml +3 -2
  66. data/tracks/idris/bin/fetch-idris-testing.sh +11 -0
  67. data/tracks/idris/bin/solve_exercises.sh +2 -2
  68. data/tracks/idris/config.json +11 -0
  69. data/tracks/idris/config/exercise_readme.go.tmpl +0 -3
  70. data/tracks/idris/docs/INSTALLATION.md +22 -0
  71. data/tracks/idris/docs/TESTS.md +12 -4
  72. data/tracks/idris/exercises/accumulate/src/Accumulate.idr +5 -0
  73. data/tracks/idris/exercises/hamming/Hamming.ipkg +2 -0
  74. data/tracks/idris/exercises/hamming/src/{example.idr → Example.idr} +5 -1
  75. data/tracks/idris/exercises/hamming/src/Hamming.idr +13 -5
  76. data/tracks/idris/exercises/hamming/src/Test/Hamming.idr +31 -58
  77. data/tracks/idris/exercises/hello-world/HelloWorld.ipkg +2 -0
  78. data/tracks/idris/exercises/hello-world/src/Example.idr +9 -0
  79. data/tracks/idris/exercises/hello-world/src/HelloWorld.idr +6 -1
  80. data/tracks/idris/exercises/hello-world/src/Test/HelloWorld.idr +18 -18
  81. data/tracks/idris/exercises/leap/Leap.ipkg +2 -0
  82. data/tracks/idris/exercises/leap/src/{example.idr → Example.idr} +4 -0
  83. data/tracks/idris/exercises/leap/src/Leap.idr +5 -1
  84. data/tracks/idris/exercises/leap/src/Test/Leap.idr +21 -30
  85. data/tracks/idris/exercises/rna-transcription/Makefile +23 -0
  86. data/tracks/idris/exercises/rna-transcription/README.md +27 -0
  87. data/tracks/idris/exercises/rna-transcription/RnaTranscription.ipkg +5 -0
  88. data/tracks/idris/exercises/rna-transcription/src/RnaTranscription.idr +17 -0
  89. data/tracks/idris/exercises/rna-transcription/src/Test/RnaTranscription.idr +27 -0
  90. data/tracks/idris/exercises/rna-transcription/src/example.idr +35 -0
  91. data/tracks/java/exercises/etl/.meta/version +1 -0
  92. data/tracks/java/exercises/gigasecond/.meta/version +1 -0
  93. data/tracks/java/exercises/isbn-verifier/README.md +1 -1
  94. data/tracks/java/exercises/nucleotide-count/.meta/src/reference/java/NucleotideCounter.java +7 -1
  95. data/tracks/java/exercises/nucleotide-count/.meta/version +1 -0
  96. data/tracks/java/exercises/nucleotide-count/src/test/java/NucleotideCounterTest.java +19 -54
  97. data/tracks/java/exercises/proverb/.meta/version +1 -0
  98. data/tracks/java/exercises/reverse-string/README.md +1 -1
  99. data/tracks/java/exercises/rna-transcription/README.md +1 -1
  100. data/tracks/java/exercises/sum-of-multiples/.meta/version +1 -0
  101. data/tracks/java/exercises/sum-of-multiples/src/test/java/SumOfMultiplesTest.java +13 -1
  102. data/tracks/kotlin/config/exercise_readme.go.tmpl +0 -3
  103. data/tracks/kotlin/docs/TESTS.md +1 -1
  104. data/tracks/objective-c/config.json +11 -0
  105. data/tracks/objective-c/exercises/collatz-conjecture/CollatzConjectureExample.h +7 -0
  106. data/tracks/objective-c/exercises/collatz-conjecture/CollatzConjectureExample.m +26 -0
  107. data/tracks/objective-c/exercises/collatz-conjecture/CollatzConjectureTest.m +39 -0
  108. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +31 -1
  109. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/xcshareddata/xcschemes/OCLint.xcscheme +3 -1
  110. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/xcshareddata/xcschemes/xobjectivecTest.xcscheme +3 -1
  111. data/tracks/ocaml/exercises/forth/example.ml +9 -9
  112. data/tracks/ocaml/tools/test-generator/Makefile +3 -9
  113. data/tracks/ocaml/tools/test-generator/src/test_gen.ml +18 -16
  114. data/tracks/perl6/exercises/acronym/.meta/exercise-data.yaml +1 -1
  115. data/tracks/perl6/exercises/acronym/acronym.t +4 -14
  116. data/tracks/perl6/exercises/all-your-base/all-your-base.t +0 -2
  117. data/tracks/perl6/exercises/allergies/allergies.t +0 -2
  118. data/tracks/perl6/exercises/anagram/.meta/exercise-data.yaml +1 -1
  119. data/tracks/perl6/exercises/anagram/anagram.t +2 -40
  120. data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +0 -1
  121. data/tracks/perl6/exercises/bob/bob.t +0 -2
  122. data/tracks/perl6/exercises/clock/.meta/exercise-data.yaml +15 -11
  123. data/tracks/perl6/exercises/clock/.meta/solutions/Clock.pm6 +5 -1
  124. data/tracks/perl6/exercises/clock/Clock.pm6 +1 -1
  125. data/tracks/perl6/exercises/clock/clock.t +314 -217
  126. data/tracks/perl6/exercises/etl/etl.t +0 -2
  127. data/tracks/perl6/exercises/flatten-array/flatten-array.t +0 -2
  128. data/tracks/perl6/exercises/grains/grains.t +0 -2
  129. data/tracks/perl6/exercises/hamming/.meta/exercise-data.yaml +2 -2
  130. data/tracks/perl6/exercises/hamming/hamming.t +63 -35
  131. data/tracks/perl6/exercises/hello-world/hello-world.t +2 -3
  132. data/tracks/perl6/exercises/leap/.meta/exercise-data.yaml +1 -1
  133. data/tracks/perl6/exercises/leap/leap.t +14 -8
  134. data/tracks/perl6/exercises/luhn/luhn.t +0 -2
  135. data/tracks/perl6/exercises/nucleotide-count/.meta/exercise-data.yaml +2 -2
  136. data/tracks/perl6/exercises/nucleotide-count/nucleotide-count.t +18 -10
  137. data/tracks/perl6/exercises/pangram/.meta/exercise-data.yaml +1 -1
  138. data/tracks/perl6/exercises/pangram/pangram.t +32 -14
  139. data/tracks/perl6/exercises/phone-number/.meta/exercise-data.yaml +4 -4
  140. data/tracks/perl6/exercises/phone-number/.meta/solutions/Phone.pm6 +1 -1
  141. data/tracks/perl6/exercises/phone-number/Phone.pm6 +1 -1
  142. data/tracks/perl6/exercises/phone-number/phone-number.t +59 -21
  143. data/tracks/perl6/exercises/raindrops/raindrops.t +0 -2
  144. data/tracks/perl6/exercises/rna-transcription/.meta/exercise-data.yaml +1 -1
  145. data/tracks/perl6/exercises/rna-transcription/README.md +1 -1
  146. data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +17 -9
  147. data/tracks/perl6/exercises/roman-numerals/.meta/exercise-data.yaml +3 -3
  148. data/tracks/perl6/exercises/roman-numerals/.meta/solutions/RomanNumerals.pm6 +1 -1
  149. data/tracks/perl6/exercises/roman-numerals/RomanNumerals.pm6 +1 -1
  150. data/tracks/perl6/exercises/roman-numerals/roman-numerals.t +66 -24
  151. data/tracks/perl6/exercises/scrabble-score/.meta/exercise-data.yaml +1 -1
  152. data/tracks/perl6/exercises/scrabble-score/scrabble-score.t +35 -15
  153. data/tracks/perl6/exercises/space-age/.meta/exercise-data.yaml +1 -1
  154. data/tracks/perl6/exercises/space-age/space-age.t +34 -20
  155. data/tracks/perl6/exercises/two-fer/.meta/exercise-data.yaml +2 -2
  156. data/tracks/perl6/exercises/two-fer/two-fer.t +15 -11
  157. data/tracks/perl6/exercises/word-count/.meta/exercise-data.yaml +1 -1
  158. data/tracks/perl6/exercises/word-count/word-count.t +46 -26
  159. data/tracks/perl6/exercises/wordy/.meta/exercise-data.yaml +2 -2
  160. data/tracks/perl6/exercises/wordy/wordy.t +51 -21
  161. data/tracks/perl6/lib/Exercism/Generator.pm6 +1 -1
  162. data/tracks/perl6/t/generated-tests.t +1 -1
  163. data/tracks/perl6/templates/test.mustache +0 -1
  164. data/tracks/python/config.json +12 -0
  165. data/tracks/python/exercises/forth/example.py +1 -1
  166. data/tracks/python/exercises/forth/forth_test.py +43 -38
  167. data/tracks/python/exercises/spiral-matrix/README.md +42 -0
  168. data/tracks/python/exercises/spiral-matrix/example.py +11 -0
  169. data/tracks/python/exercises/spiral-matrix/spiral_matrix.py +2 -0
  170. data/tracks/python/exercises/spiral-matrix/spiral_matrix_test.py +40 -0
  171. data/tracks/racket/config/exercise_readme.go.tmpl +24 -4
  172. data/tracks/racket/exercises/accumulate/README.md +3 -6
  173. data/tracks/racket/exercises/acronym/README.md +3 -4
  174. data/tracks/racket/exercises/allergies/README.md +3 -4
  175. data/tracks/racket/exercises/anagram/README.md +3 -3
  176. data/tracks/racket/exercises/bob/README.md +5 -3
  177. data/tracks/racket/exercises/collatz-conjecture/README.md +3 -3
  178. data/tracks/racket/exercises/difference-of-squares/README.md +3 -3
  179. data/tracks/racket/exercises/etl/README.md +6 -4
  180. data/tracks/racket/exercises/gigasecond/README.md +3 -3
  181. data/tracks/racket/exercises/grains/README.md +3 -4
  182. data/tracks/racket/exercises/grep/README.md +15 -15
  183. data/tracks/racket/exercises/hamming/README.md +3 -3
  184. data/tracks/racket/exercises/hello-world/README.md +1 -1
  185. data/tracks/racket/exercises/leap/README.md +4 -4
  186. data/tracks/racket/exercises/list-ops/README.md +3 -4
  187. data/tracks/racket/exercises/meetup/README.md +19 -15
  188. data/tracks/racket/exercises/nucleotide-count/README.md +11 -25
  189. data/tracks/racket/exercises/perfect-numbers/README.md +5 -5
  190. data/tracks/racket/exercises/phone-number/README.md +7 -6
  191. data/tracks/racket/exercises/raindrops/README.md +3 -3
  192. data/tracks/racket/exercises/rna-transcription/README.md +4 -4
  193. data/tracks/racket/exercises/roman-numerals/README.md +4 -4
  194. data/tracks/racket/exercises/say/README.md +3 -3
  195. data/tracks/racket/exercises/scrabble-score/README.md +6 -4
  196. data/tracks/racket/exercises/word-count/README.md +4 -5
  197. data/tracks/scheme/config/exercise_readme.go.tmpl +0 -3
  198. data/tracks/scheme/docs/INSTALLATION.md +23 -14
  199. metadata +40 -9
  200. data/tracks/idris/docs/EXERCISE_README_INSERT.md +0 -0
  201. data/tracks/idris/exercises/hello-world/src/example.idr +0 -5
  202. data/tracks/kotlin/config/exercise-readme-insert.md +0 -1
  203. data/tracks/racket/docs/EXERCISE_README_INSERT.md +0 -23
  204. data/tracks/scheme/docs/EXERCISE_README_INSERT.md +0 -0
@@ -0,0 +1,16 @@
1
+ ## Implementation
2
+
3
+ In package twobucket, implement a Go func, Solve, with
4
+ the following signature:
5
+
6
+ ```
7
+ func Solve(sizeBucketOne,
8
+ sizeBucketTwo,
9
+ goalAmount int,
10
+ startBucket string) (goalBucket string, numSteps, otherBucketLevel int, e error)
11
+ ```
12
+ Solve returns four values: the resulting goal bucket("one" or two"),
13
+ the number of moves/steps to achieve the goal amount,
14
+ the liters left in the other bucket,
15
+ and an error value. The returned error value should be nil for valid parameters,
16
+ or an error for invalid parameters.
@@ -0,0 +1,72 @@
1
+ # Two Bucket
2
+
3
+ Given two buckets of different size, demonstrate how to measure an exact number of liters by strategically transferring liters of fluid between the buckets.
4
+
5
+ Since this mathematical problem is fairly subject to interpretation / individual approach, the tests have been written specifically to expect one overarching solution.
6
+
7
+ To help, the tests provide you with which bucket to fill first. That means, when starting with the larger bucket full, you are NOT allowed at any point to have the smaller bucket full and the larger bucket empty (aka, the opposite starting point); that would defeat the purpose of comparing both approaches!
8
+
9
+ Your program will take as input:
10
+ - the size of bucket one
11
+ - the size of bucket two
12
+ - the desired number of liters to reach
13
+ - which bucket to fill first, either bucket one or bucket two
14
+
15
+ Your program should determine:
16
+ - the total number of "moves" it should take to reach the desired number of liters, including the first fill
17
+ - which bucket should end up with the desired number of liters (let's say this is bucket A) - either bucket one or bucket two
18
+ - how many liters are left in the other bucket (bucket B)
19
+
20
+ Note: any time a change is made to either or both buckets counts as one (1) move.
21
+
22
+ Example:
23
+ Bucket one can hold up to 7 liters, and bucket two can hold up to 11 liters. Let's say bucket one, at a given step, is holding 7 liters, and bucket two is holding 8 liters (7,8). If you empty bucket one and make no change to bucket two, leaving you with 0 liters and 8 liters respectively (0,8), that counts as one "move". Instead, if you had poured from bucket one into bucket two until bucket two was full, leaving you with 4 liters in bucket one and 11 liters in bucket two (4,11), that would count as only one "move" as well.
24
+
25
+ To conclude, the only valid moves are:
26
+ - pouring from one bucket to another
27
+ - emptying one bucket and doing nothing to the other
28
+ - filling one bucket and doing nothing to the other
29
+
30
+ Written with <3 at [Fullstack Academy](http://www.fullstackacademy.com/) by [Lindsay](http://lindsaylevine.com).
31
+
32
+ ## Implementation
33
+
34
+ In package twobucket, implement a Go func, Solve, with
35
+ the following signature:
36
+
37
+ ```
38
+ func Solve(sizeBucketOne,
39
+ sizeBucketTwo,
40
+ goalAmount int,
41
+ startBucket string) (goalBucket string, numSteps, otherBucketLevel int, e error)
42
+ ```
43
+ Solve returns four values: the resulting goal bucket("one" or two"),
44
+ the number of moves/steps to achieve the goal amount,
45
+ the liters left in the other bucket,
46
+ and an error value. The returned error value should be nil for valid parameters,
47
+ or an error for invalid parameters.
48
+
49
+
50
+ ## Running the tests
51
+
52
+ To run the tests run the command `go test` from within the exercise directory.
53
+
54
+ If the test suite contains benchmarks, you can run these with the `-bench`
55
+ flag:
56
+
57
+ go test -bench .
58
+
59
+ Keep in mind that each reviewer will run benchmarks on a different machine, with
60
+ different specs, so the results from these benchmark tests may vary.
61
+
62
+ ## Further information
63
+
64
+ For more detailed information about the Go track, including how to get help if
65
+ you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/about).
66
+
67
+ ## Source
68
+
69
+ Water Pouring Problem [http://demonstrations.wolfram.com/WaterPouringProblem/](http://demonstrations.wolfram.com/WaterPouringProblem/)
70
+
71
+ ## Submitting Incomplete Solutions
72
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,44 @@
1
+ package twobucket
2
+
3
+ // Source: exercism/problem-specifications
4
+ // Commit: edbc86b two-bucket: apply lowerCamelCase rule to variables
5
+ // Problem Specifications Version: 1.4.0
6
+
7
+ type bucketTestCase struct {
8
+ description string
9
+ bucketOne int
10
+ bucketTwo int
11
+ goal int
12
+ startBucket string
13
+ goalBucket string
14
+ moves int
15
+ otherBucket int
16
+ errorExpected bool // always false for generated test cases.
17
+ }
18
+
19
+ var testCases = []bucketTestCase{
20
+ {
21
+ "Measure using bucket one of size 3 and bucket two of size 5 - start with bucket one",
22
+ 3, 5, 1, "one", "one", 4, 5, false,
23
+ },
24
+ {
25
+ "Measure using bucket one of size 3 and bucket two of size 5 - start with bucket two",
26
+ 3, 5, 1, "two", "two", 8, 3, false,
27
+ },
28
+ {
29
+ "Measure using bucket one of size 7 and bucket two of size 11 - start with bucket one",
30
+ 7, 11, 2, "one", "one", 14, 11, false,
31
+ },
32
+ {
33
+ "Measure using bucket one of size 7 and bucket two of size 11 - start with bucket two",
34
+ 7, 11, 2, "two", "two", 18, 7, false,
35
+ },
36
+ {
37
+ "Measure one step using bucket one of size 1 and bucket two of size 3 - start with bucket two",
38
+ 1, 3, 3, "two", "two", 1, 0, false,
39
+ },
40
+ {
41
+ "Measure using bucket one of size 2 and bucket two of size 3 - start with bucket one and end with bucket two",
42
+ 2, 3, 3, "one", "two", 2, 2, false,
43
+ },
44
+ }
@@ -0,0 +1,198 @@
1
+ package twobucket
2
+
3
+ import (
4
+ "errors"
5
+ )
6
+
7
+ type bucket int
8
+
9
+ const (
10
+ bOne bucket = iota
11
+ bTwo
12
+ )
13
+
14
+ type step int
15
+
16
+ const (
17
+ none step = iota
18
+ emptyOne
19
+ emptyTwo
20
+ fillOne
21
+ fillTwo
22
+ pourOneToTwo
23
+ pourTwoToOne
24
+ )
25
+
26
+ type problem struct {
27
+ capacity [2]int
28
+ goal int
29
+ start bucket
30
+ }
31
+
32
+ type state struct {
33
+ level [2]int
34
+ previousStep step
35
+ numSteps int
36
+ }
37
+
38
+ const (
39
+ FirstBucketName = "one"
40
+ SecondBucketName = "two"
41
+ )
42
+
43
+ // Solve uses given bucket sizes, the goal amount, and starting bucket to
44
+ // solve the two-bucket problem to measure exactly the goal mount,
45
+ // returning the goal bucket name "one" or "two",
46
+ // the required number of steps, and the fill-level of the other bucket.
47
+ func Solve(sizeBucketOne,
48
+ sizeBucketTwo,
49
+ goalAmount int,
50
+ startBucket string) (goalBucket string, numSteps, otherBucketLevel int, e error) {
51
+
52
+ if e = validateParameters(sizeBucketOne, sizeBucketTwo, goalAmount, startBucket); e != nil {
53
+ return "", 0, 0, e
54
+ }
55
+
56
+ p := problem{
57
+ capacity: [2]int{sizeBucketOne, sizeBucketTwo},
58
+ goal: goalAmount,
59
+ }
60
+ var s state
61
+ if startBucket == FirstBucketName {
62
+ p.start = bOne
63
+ performStep(p, &s, fillOne)
64
+ } else {
65
+ p.start = bTwo
66
+ performStep(p, &s, fillTwo)
67
+ }
68
+ // Initial step might be a solution.
69
+ if !isSolution(p, s) {
70
+ s = findGoal(p, s)
71
+ }
72
+ if s.level[bOne] == p.goal {
73
+ return FirstBucketName, s.numSteps, s.level[bTwo], nil
74
+ }
75
+ return SecondBucketName, s.numSteps, s.level[bOne], nil
76
+ }
77
+
78
+ func validateParameters(sizeBucketOne, sizeBucketTwo, goalAmount int, startBucket string) error {
79
+ if sizeBucketOne <= 0 {
80
+ return errors.New("sizeBucketOne invalid")
81
+ }
82
+ if sizeBucketTwo <= 0 {
83
+ return errors.New("sizeBucketTwo invalid")
84
+ }
85
+ if goalAmount <= 0 {
86
+ return errors.New("goalAmount invalid")
87
+ }
88
+ if startBucket != FirstBucketName && startBucket != SecondBucketName {
89
+ return errors.New("startBucket invalid")
90
+ }
91
+ return nil
92
+ }
93
+
94
+ func isSolution(p problem, s state) bool {
95
+ return s.level[bOne] == p.goal || s.level[bTwo] == p.goal
96
+ }
97
+
98
+ func findGoal(p problem, s state) (g state) {
99
+ searchList := make([]state, 1)
100
+ searchList[0] = s
101
+
102
+ // Use breadth-first search to find the goal, tracking any previously visited states.
103
+ visited := map[[2]int]bool{}
104
+
105
+ // Mark as already visited two invalid bucket levels: 0,0 and the reverse starting position.
106
+ visited[[2]int{0, 0}] = true
107
+ if p.start == bOne {
108
+ visited[[2]int{0, p.capacity[bTwo]}] = true
109
+ } else {
110
+ visited[[2]int{p.capacity[bOne], 0}] = true
111
+ }
112
+
113
+ for {
114
+ // Pop one item from the searchList each pass.
115
+ current := searchList[0]
116
+ searchList = searchList[1:]
117
+
118
+ for _, x := range getPossibleSteps(p, current) {
119
+ next := current
120
+ performStep(p, &next, x)
121
+ if isSolution(p, next) {
122
+ return next
123
+ }
124
+ if !visited[next.level] {
125
+ searchList = append(searchList, next)
126
+ visited[next.level] = true
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+ func performStep(p problem, s *state, x step) {
133
+ switch x {
134
+ case emptyOne:
135
+ s.level[bOne] = 0
136
+ case emptyTwo:
137
+ s.level[bTwo] = 0
138
+ case fillOne:
139
+ s.level[bOne] = p.capacity[bOne]
140
+ case fillTwo:
141
+ s.level[bTwo] = p.capacity[bTwo]
142
+ case pourOneToTwo:
143
+ pour(p, s, bOne, bTwo)
144
+ case pourTwoToOne:
145
+ pour(p, s, bTwo, bOne)
146
+ }
147
+ s.numSteps++
148
+ s.previousStep = x
149
+ }
150
+
151
+ // pour from bucket a to b.
152
+ func pour(p problem, s *state, a, b bucket) {
153
+ amount := p.capacity[b] - s.level[b]
154
+ if amount > s.level[a] {
155
+ amount = s.level[a]
156
+ }
157
+ s.level[b] += amount
158
+ s.level[a] -= amount
159
+ }
160
+
161
+ func getPossibleSteps(p problem, s state) (list []step) {
162
+ for x := emptyOne; x <= pourTwoToOne; x++ {
163
+ if canPeformStep(p, s, x) {
164
+ list = append(list, x)
165
+ }
166
+ }
167
+ return list
168
+ }
169
+
170
+ func canPeformStep(p problem, s state, x step) bool {
171
+ switch x {
172
+ case emptyOne:
173
+ if s.previousStep == fillOne || s.previousStep == pourOneToTwo {
174
+ return false
175
+ }
176
+ return s.level[bOne] != 0
177
+ case emptyTwo:
178
+ if s.previousStep == fillTwo || s.previousStep == pourTwoToOne {
179
+ return false
180
+ }
181
+ return s.level[bTwo] != 0
182
+ case fillOne:
183
+ if s.previousStep == emptyOne || s.level[bOne] == p.capacity[bOne] {
184
+ return false
185
+ }
186
+ return true
187
+ case fillTwo:
188
+ if s.previousStep == emptyTwo || s.level[bTwo] == p.capacity[bTwo] {
189
+ return false
190
+ }
191
+ return true
192
+ case pourOneToTwo:
193
+ return s.level[bOne] != 0 && s.level[bTwo] < p.capacity[bTwo]
194
+ case pourTwoToOne:
195
+ return s.level[bTwo] != 0 && s.level[bOne] < p.capacity[bOne]
196
+ }
197
+ return false
198
+ }
@@ -0,0 +1,61 @@
1
+ package twobucket
2
+
3
+ import "testing"
4
+
5
+ func TestSolve(t *testing.T) {
6
+ for _, tc := range append(testCases, errorTestCases...) {
7
+ g, m, other, e := Solve(tc.bucketOne, tc.bucketTwo, tc.goal, tc.startBucket)
8
+ var _ error = e
9
+ if e == nil {
10
+ if tc.errorExpected {
11
+ t.Fatalf("FAIL: %s\nSolve(%d, %d, %d, %q)\nExpected error\nActual: %q, %d, %d",
12
+ tc.description,
13
+ tc.bucketOne, tc.bucketTwo, tc.goal, tc.startBucket,
14
+ g, m, other)
15
+ }
16
+ if g != tc.goalBucket || m != tc.moves || other != tc.otherBucket {
17
+ t.Fatalf("FAIL: %s\nSolve(%d, %d, %d, %q)\nExpected: %q, %d, %d\nActual: %q, %d, %d",
18
+ tc.description,
19
+ tc.bucketOne, tc.bucketTwo, tc.goal, tc.startBucket,
20
+ tc.goalBucket, tc.moves, tc.otherBucket,
21
+ g, m, other)
22
+ }
23
+ } else if e != nil {
24
+ if !tc.errorExpected {
25
+ t.Fatalf("FAIL: %s\nSolve(%d, %d, %d, %q)\nExpected: %q, %d, %d\nnGot Error %q",
26
+ tc.description,
27
+ tc.bucketOne, tc.bucketTwo, tc.goal, tc.startBucket,
28
+ tc.goalBucket, tc.moves, tc.otherBucket,
29
+ e)
30
+ }
31
+ }
32
+ t.Logf("PASS: %s", tc.description)
33
+ }
34
+ }
35
+
36
+ func BenchmarkSolve(b *testing.B) {
37
+ for i := 0; i < b.N; i++ {
38
+ for _, tc := range testCases {
39
+ Solve(tc.bucketOne, tc.bucketTwo, tc.goal, tc.startBucket)
40
+ }
41
+ }
42
+ }
43
+
44
+ var errorTestCases = []bucketTestCase{
45
+ {
46
+ "Invalid first bucket size",
47
+ 0, 5, 5, "one", "one", 1, 0, true,
48
+ },
49
+ {
50
+ "Invalid second bucket size",
51
+ 3, 0, 3, "one", "one", 1, 0, true,
52
+ },
53
+ {
54
+ "Invalid goal amount",
55
+ 1, 1, 0, "one", "one", 0, 1, true,
56
+ },
57
+ {
58
+ "Invalid start bucket name",
59
+ 3, 5, 1, "three", "one", 4, 5, true,
60
+ },
61
+ }
@@ -19,7 +19,8 @@ install:
19
19
  - bin/fetch-exercism-infra.sh
20
20
  - stack --resolver $RESOLVER setup
21
21
  - "[[ $(which idris) != '' ]] || travis_wait 60 stack --resolver $RESOLVER install idris"
22
+ - bin/fetch-idris-testing.sh
22
23
 
23
24
  script:
24
- - bin/configlet .
25
- - bin/solve_exercises.sh
25
+ - bin/configlet lint .
26
+ - bin/solve_exercises.sh
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -x
4
+
5
+ mkdir -p build
6
+ git clone https://github.com/yurrriq/idris-testing.git build/idris-testing
7
+
8
+ pushd build/idris-testing
9
+ make lib
10
+ make install
11
+ popd
@@ -29,7 +29,7 @@ for exercise in $exercises; do
29
29
 
30
30
  ${exercism_command} fetch idris ${exercise} # TODO: track name!
31
31
  exercise_implementation=$(ls ${exercism_home}/idris/${exercise}/src/*.idr)
32
- exercise_example=${xtrack_home}/exercises/${exercise}/src/example.idr
32
+ exercise_example=${xtrack_home}/exercises/${exercise}/src/Example.idr
33
33
  cp ${exercise_example} ${exercise_implementation}
34
34
 
35
35
  pushd ${exercism_home}/idris/${exercise}
@@ -56,4 +56,4 @@ for i in ${red[@]}; do
56
56
  echo " * ${i}"
57
57
  done
58
58
 
59
- exit $exit_code
59
+ exit $exit_code
@@ -7,6 +7,17 @@
7
7
 
8
8
  ],
9
9
  "exercises": [
10
+ {
11
+ "core": false,
12
+ "difficulty": 1,
13
+ "slug": "rna-transcription",
14
+ "topics" : [
15
+ "pattern_matching",
16
+ "vectors"
17
+ ],
18
+ "unlocked_by": null,
19
+ "uuid": "3640da6c-4f1d-483c-8990-de225fcb0b03"
20
+ },
10
21
  {
11
22
  "core": false,
12
23
  "difficulty": 1,