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.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/kindergarten-garden/canonical-data.json +37 -19
- data/problem-specifications/exercises/ocr-numbers/canonical-data.json +144 -110
- data/problem-specifications/exercises/palindrome-products/canonical-data.json +49 -25
- data/problem-specifications/exercises/poker/canonical-data.json +171 -115
- data/problem-specifications/exercises/prime-factors/canonical-data.json +22 -8
- data/problem-specifications/exercises/protein-translation/canonical-data.json +70 -24
- data/problem-specifications/exercises/proverb/canonical-data.json +24 -12
- data/problem-specifications/exercises/queen-attack/canonical-data.json +115 -91
- data/problem-specifications/exercises/rail-fence-cipher/canonical-data.json +25 -13
- data/problem-specifications/exercises/raindrops/canonical-data.json +55 -19
- data/problem-specifications/exercises/rational-numbers/canonical-data.json +374 -0
- data/problem-specifications/exercises/rational-numbers/description.md +27 -0
- data/problem-specifications/exercises/rational-numbers/metadata.yml +4 -0
- data/problem-specifications/exercises/rectangles/canonical-data.json +93 -67
- data/problem-specifications/exercises/reverse-string/canonical-data.json +16 -6
- data/problem-specifications/exercises/rna-transcription/metadata.yml +3 -3
- data/problem-specifications/exercises/roman-numerals/canonical-data.json +10 -2
- data/tracks/bash/config.json +11 -11
- data/tracks/c/exercises/roman-numerals/test/test_roman_numerals.c +7 -0
- data/tracks/clojure/exercises/armstrong-numbers/README.md +1 -1
- data/tracks/delphi/config.json +11 -0
- data/tracks/delphi/exercises/clock/uClockExample.pas +6 -1
- data/tracks/delphi/exercises/clock/uClockTest.pas +22 -19
- data/tracks/delphi/exercises/isbn-verifier/README.md +1 -1
- data/tracks/delphi/exercises/reverse-string/README.md +1 -1
- data/tracks/delphi/exercises/rna-transcription/README.md +1 -1
- data/tracks/delphi/exercises/roman-numerals/uRomanNumeralsTest.pas +14 -0
- data/tracks/delphi/exercises/space-age/README.md +45 -0
- data/tracks/delphi/exercises/space-age/SpaceAge.dpr +60 -0
- data/tracks/delphi/exercises/space-age/uSpaceAgeExample.pas +120 -0
- data/tracks/delphi/exercises/space-age/uSpaceAgeTests.pas +135 -0
- data/tracks/delphi/exercises/two-fer/README.md +1 -1
- data/tracks/elixir/exercises/nth-prime/nth_prime.exs +0 -1
- data/tracks/fsharp/exercises/pov/PovTest.fs +66 -53
- data/tracks/fsharp/exercises/space-age/Example.fs +11 -11
- data/tracks/fsharp/exercises/space-age/SpaceAge.fs +1 -1
- data/tracks/fsharp/exercises/space-age/SpaceAgeTest.fs +21 -34
- data/tracks/fsharp/exercises/triangle/Example.fs +11 -16
- data/tracks/fsharp/exercises/triangle/Triangle.fs +4 -5
- data/tracks/fsharp/exercises/triangle/TriangleTest.fs +44 -31
- data/tracks/fsharp/generators/Generators.fs +121 -0
- data/tracks/go/config.json +12 -0
- data/tracks/go/exercises/clock/.meta/gen.go +37 -13
- data/tracks/go/exercises/clock/cases_test.go +10 -10
- data/tracks/go/exercises/clock/clock_test.go +16 -2
- data/tracks/go/exercises/clock/example.go +4 -0
- data/tracks/go/exercises/clock/example_clock_test.go +3 -3
- data/tracks/go/exercises/parallel-letter-frequency/.meta/hints.md +33 -0
- data/tracks/go/exercises/parallel-letter-frequency/README.md +35 -0
- data/tracks/go/exercises/raindrops/.meta/hints.md +7 -4
- data/tracks/go/exercises/raindrops/README.md +12 -0
- data/tracks/go/exercises/roman-numerals/.meta/gen.go +4 -2
- data/tracks/go/exercises/roman-numerals/cases_test.go +3 -2
- data/tracks/go/exercises/space-age/.meta/hints.md +10 -0
- data/tracks/go/exercises/space-age/README.md +14 -1
- data/tracks/go/exercises/twelve-days/README.md +2 -5
- data/tracks/go/exercises/two-bucket/.meta/gen.go +62 -0
- data/tracks/go/exercises/two-bucket/.meta/hints.md +16 -0
- data/tracks/go/exercises/two-bucket/README.md +72 -0
- data/tracks/go/exercises/two-bucket/cases_test.go +44 -0
- data/tracks/go/exercises/two-bucket/example.go +198 -0
- data/tracks/go/exercises/two-bucket/two_bucket_test.go +61 -0
- data/tracks/idris/.travis.yml +3 -2
- data/tracks/idris/bin/fetch-idris-testing.sh +11 -0
- data/tracks/idris/bin/solve_exercises.sh +2 -2
- data/tracks/idris/config.json +11 -0
- data/tracks/idris/config/exercise_readme.go.tmpl +0 -3
- data/tracks/idris/docs/INSTALLATION.md +22 -0
- data/tracks/idris/docs/TESTS.md +12 -4
- data/tracks/idris/exercises/accumulate/src/Accumulate.idr +5 -0
- data/tracks/idris/exercises/hamming/Hamming.ipkg +2 -0
- data/tracks/idris/exercises/hamming/src/{example.idr → Example.idr} +5 -1
- data/tracks/idris/exercises/hamming/src/Hamming.idr +13 -5
- data/tracks/idris/exercises/hamming/src/Test/Hamming.idr +31 -58
- data/tracks/idris/exercises/hello-world/HelloWorld.ipkg +2 -0
- data/tracks/idris/exercises/hello-world/src/Example.idr +9 -0
- data/tracks/idris/exercises/hello-world/src/HelloWorld.idr +6 -1
- data/tracks/idris/exercises/hello-world/src/Test/HelloWorld.idr +18 -18
- data/tracks/idris/exercises/leap/Leap.ipkg +2 -0
- data/tracks/idris/exercises/leap/src/{example.idr → Example.idr} +4 -0
- data/tracks/idris/exercises/leap/src/Leap.idr +5 -1
- data/tracks/idris/exercises/leap/src/Test/Leap.idr +21 -30
- data/tracks/idris/exercises/rna-transcription/Makefile +23 -0
- data/tracks/idris/exercises/rna-transcription/README.md +27 -0
- data/tracks/idris/exercises/rna-transcription/RnaTranscription.ipkg +5 -0
- data/tracks/idris/exercises/rna-transcription/src/RnaTranscription.idr +17 -0
- data/tracks/idris/exercises/rna-transcription/src/Test/RnaTranscription.idr +27 -0
- data/tracks/idris/exercises/rna-transcription/src/example.idr +35 -0
- data/tracks/java/exercises/etl/.meta/version +1 -0
- data/tracks/java/exercises/gigasecond/.meta/version +1 -0
- data/tracks/java/exercises/isbn-verifier/README.md +1 -1
- data/tracks/java/exercises/nucleotide-count/.meta/src/reference/java/NucleotideCounter.java +7 -1
- data/tracks/java/exercises/nucleotide-count/.meta/version +1 -0
- data/tracks/java/exercises/nucleotide-count/src/test/java/NucleotideCounterTest.java +19 -54
- data/tracks/java/exercises/proverb/.meta/version +1 -0
- data/tracks/java/exercises/reverse-string/README.md +1 -1
- data/tracks/java/exercises/rna-transcription/README.md +1 -1
- data/tracks/java/exercises/sum-of-multiples/.meta/version +1 -0
- data/tracks/java/exercises/sum-of-multiples/src/test/java/SumOfMultiplesTest.java +13 -1
- data/tracks/kotlin/config/exercise_readme.go.tmpl +0 -3
- data/tracks/kotlin/docs/TESTS.md +1 -1
- data/tracks/objective-c/config.json +11 -0
- data/tracks/objective-c/exercises/collatz-conjecture/CollatzConjectureExample.h +7 -0
- data/tracks/objective-c/exercises/collatz-conjecture/CollatzConjectureExample.m +26 -0
- data/tracks/objective-c/exercises/collatz-conjecture/CollatzConjectureTest.m +39 -0
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +31 -1
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/xcshareddata/xcschemes/OCLint.xcscheme +3 -1
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/xcshareddata/xcschemes/xobjectivecTest.xcscheme +3 -1
- data/tracks/ocaml/exercises/forth/example.ml +9 -9
- data/tracks/ocaml/tools/test-generator/Makefile +3 -9
- data/tracks/ocaml/tools/test-generator/src/test_gen.ml +18 -16
- data/tracks/perl6/exercises/acronym/.meta/exercise-data.yaml +1 -1
- data/tracks/perl6/exercises/acronym/acronym.t +4 -14
- data/tracks/perl6/exercises/all-your-base/all-your-base.t +0 -2
- data/tracks/perl6/exercises/allergies/allergies.t +0 -2
- data/tracks/perl6/exercises/anagram/.meta/exercise-data.yaml +1 -1
- data/tracks/perl6/exercises/anagram/anagram.t +2 -40
- data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +0 -1
- data/tracks/perl6/exercises/bob/bob.t +0 -2
- data/tracks/perl6/exercises/clock/.meta/exercise-data.yaml +15 -11
- data/tracks/perl6/exercises/clock/.meta/solutions/Clock.pm6 +5 -1
- data/tracks/perl6/exercises/clock/Clock.pm6 +1 -1
- data/tracks/perl6/exercises/clock/clock.t +314 -217
- data/tracks/perl6/exercises/etl/etl.t +0 -2
- data/tracks/perl6/exercises/flatten-array/flatten-array.t +0 -2
- data/tracks/perl6/exercises/grains/grains.t +0 -2
- data/tracks/perl6/exercises/hamming/.meta/exercise-data.yaml +2 -2
- data/tracks/perl6/exercises/hamming/hamming.t +63 -35
- data/tracks/perl6/exercises/hello-world/hello-world.t +2 -3
- data/tracks/perl6/exercises/leap/.meta/exercise-data.yaml +1 -1
- data/tracks/perl6/exercises/leap/leap.t +14 -8
- data/tracks/perl6/exercises/luhn/luhn.t +0 -2
- data/tracks/perl6/exercises/nucleotide-count/.meta/exercise-data.yaml +2 -2
- data/tracks/perl6/exercises/nucleotide-count/nucleotide-count.t +18 -10
- data/tracks/perl6/exercises/pangram/.meta/exercise-data.yaml +1 -1
- data/tracks/perl6/exercises/pangram/pangram.t +32 -14
- data/tracks/perl6/exercises/phone-number/.meta/exercise-data.yaml +4 -4
- data/tracks/perl6/exercises/phone-number/.meta/solutions/Phone.pm6 +1 -1
- data/tracks/perl6/exercises/phone-number/Phone.pm6 +1 -1
- data/tracks/perl6/exercises/phone-number/phone-number.t +59 -21
- data/tracks/perl6/exercises/raindrops/raindrops.t +0 -2
- data/tracks/perl6/exercises/rna-transcription/.meta/exercise-data.yaml +1 -1
- data/tracks/perl6/exercises/rna-transcription/README.md +1 -1
- data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +17 -9
- data/tracks/perl6/exercises/roman-numerals/.meta/exercise-data.yaml +3 -3
- data/tracks/perl6/exercises/roman-numerals/.meta/solutions/RomanNumerals.pm6 +1 -1
- data/tracks/perl6/exercises/roman-numerals/RomanNumerals.pm6 +1 -1
- data/tracks/perl6/exercises/roman-numerals/roman-numerals.t +66 -24
- data/tracks/perl6/exercises/scrabble-score/.meta/exercise-data.yaml +1 -1
- data/tracks/perl6/exercises/scrabble-score/scrabble-score.t +35 -15
- data/tracks/perl6/exercises/space-age/.meta/exercise-data.yaml +1 -1
- data/tracks/perl6/exercises/space-age/space-age.t +34 -20
- data/tracks/perl6/exercises/two-fer/.meta/exercise-data.yaml +2 -2
- data/tracks/perl6/exercises/two-fer/two-fer.t +15 -11
- data/tracks/perl6/exercises/word-count/.meta/exercise-data.yaml +1 -1
- data/tracks/perl6/exercises/word-count/word-count.t +46 -26
- data/tracks/perl6/exercises/wordy/.meta/exercise-data.yaml +2 -2
- data/tracks/perl6/exercises/wordy/wordy.t +51 -21
- data/tracks/perl6/lib/Exercism/Generator.pm6 +1 -1
- data/tracks/perl6/t/generated-tests.t +1 -1
- data/tracks/perl6/templates/test.mustache +0 -1
- data/tracks/python/config.json +12 -0
- data/tracks/python/exercises/forth/example.py +1 -1
- data/tracks/python/exercises/forth/forth_test.py +43 -38
- data/tracks/python/exercises/spiral-matrix/README.md +42 -0
- data/tracks/python/exercises/spiral-matrix/example.py +11 -0
- data/tracks/python/exercises/spiral-matrix/spiral_matrix.py +2 -0
- data/tracks/python/exercises/spiral-matrix/spiral_matrix_test.py +40 -0
- data/tracks/racket/config/exercise_readme.go.tmpl +24 -4
- data/tracks/racket/exercises/accumulate/README.md +3 -6
- data/tracks/racket/exercises/acronym/README.md +3 -4
- data/tracks/racket/exercises/allergies/README.md +3 -4
- data/tracks/racket/exercises/anagram/README.md +3 -3
- data/tracks/racket/exercises/bob/README.md +5 -3
- data/tracks/racket/exercises/collatz-conjecture/README.md +3 -3
- data/tracks/racket/exercises/difference-of-squares/README.md +3 -3
- data/tracks/racket/exercises/etl/README.md +6 -4
- data/tracks/racket/exercises/gigasecond/README.md +3 -3
- data/tracks/racket/exercises/grains/README.md +3 -4
- data/tracks/racket/exercises/grep/README.md +15 -15
- data/tracks/racket/exercises/hamming/README.md +3 -3
- data/tracks/racket/exercises/hello-world/README.md +1 -1
- data/tracks/racket/exercises/leap/README.md +4 -4
- data/tracks/racket/exercises/list-ops/README.md +3 -4
- data/tracks/racket/exercises/meetup/README.md +19 -15
- data/tracks/racket/exercises/nucleotide-count/README.md +11 -25
- data/tracks/racket/exercises/perfect-numbers/README.md +5 -5
- data/tracks/racket/exercises/phone-number/README.md +7 -6
- data/tracks/racket/exercises/raindrops/README.md +3 -3
- data/tracks/racket/exercises/rna-transcription/README.md +4 -4
- data/tracks/racket/exercises/roman-numerals/README.md +4 -4
- data/tracks/racket/exercises/say/README.md +3 -3
- data/tracks/racket/exercises/scrabble-score/README.md +6 -4
- data/tracks/racket/exercises/word-count/README.md +4 -5
- data/tracks/scheme/config/exercise_readme.go.tmpl +0 -3
- data/tracks/scheme/docs/INSTALLATION.md +23 -14
- metadata +40 -9
- data/tracks/idris/docs/EXERCISE_README_INSERT.md +0 -0
- data/tracks/idris/exercises/hello-world/src/example.idr +0 -5
- data/tracks/kotlin/config/exercise-readme-insert.md +0 -1
- data/tracks/racket/docs/EXERCISE_README_INSERT.md +0 -23
- 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
|
+
}
|
data/tracks/idris/.travis.yml
CHANGED
@@ -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
|
@@ -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/
|
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
|
data/tracks/idris/config.json
CHANGED
@@ -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,
|