trackler 1.0.1.0 → 1.0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -0
- data/bin/bump-content +33 -0
- data/common/exercises/bowling/canonical-data.json +78 -77
- data/common/exercises/counter/.deprecated +1 -0
- data/common/exercises/point-mutations/.deprecated +1 -0
- data/common/exercises/say/canonical-data.json +83 -0
- data/common/exercises/word-count/canonical-data.json +25 -5
- data/lib/trackler/version.rb +1 -1
- data/tracks/c/config.json +9 -0
- data/tracks/c/exercises/largest-series-product/makefile +16 -0
- data/tracks/c/exercises/largest-series-product/src/example.c +54 -0
- data/tracks/c/exercises/largest-series-product/src/example.h +9 -0
- data/tracks/c/exercises/largest-series-product/test/test_largest_series_product.c +114 -0
- data/tracks/c/exercises/largest-series-product/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/largest-series-product/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/largest-series-product/test/vendor/unity_internals.h +701 -0
- data/tracks/clojure/_test/check_exercises.clj +7 -6
- data/tracks/clojure/config.json +268 -53
- data/tracks/clojure/exercises/flatten-array/src/example.clj +16 -0
- data/tracks/clojure/exercises/flatten-array/test/flatten_array_test.clj +28 -0
- data/tracks/clojure/exercises/perfect-numbers/project.clj +4 -0
- data/tracks/clojure/exercises/perfect-numbers/src/example.clj +17 -0
- data/tracks/clojure/exercises/perfect-numbers/test/perfect_numbers_test.clj +20 -0
- data/tracks/ecmascript/exercises/grade-school/grade-school.spec.js +7 -0
- data/tracks/elixir/.travis.yml +3 -0
- data/tracks/elixir/bin/dialyzer_check.sh +28 -0
- data/tracks/elixir/config.json +13 -1
- data/tracks/elixir/docs/TESTS.md +81 -0
- data/tracks/elixir/exercises/bank-account/example.exs +1 -1
- data/tracks/elixir/exercises/binary-search/binary_search_test.exs +5 -0
- data/tracks/elixir/exercises/clock/clock.exs +23 -0
- data/tracks/elixir/exercises/clock/clock_test.exs +281 -0
- data/tracks/elixir/exercises/clock/example.exs +55 -0
- data/tracks/elixir/exercises/prime-factors/example.exs +1 -2
- data/tracks/elixir/exercises/robot-simulator/example.exs +2 -3
- data/tracks/elixir/mix.exs +2 -1
- data/tracks/go/docs/TESTS.md +1 -1
- data/tracks/go/exercises/gigasecond/gigasecond_test.go +0 -2
- data/tracks/go/exercises/palindrome-products/palindrome_products_test.go +38 -22
- data/tracks/haskell/.travis.yml +26 -7
- data/tracks/haskell/config.json +0 -69
- data/tracks/haskell/exercises/anagram/examples/list-string/Anagram.hs +10 -0
- data/tracks/haskell/exercises/anagram/examples/list-string/package.yaml +17 -0
- data/tracks/haskell/exercises/anagram/{src/Example.hs → examples/set-text/Anagram.hs} +0 -0
- data/tracks/haskell/exercises/anagram/examples/set-text/package.yaml +20 -0
- data/tracks/haskell/exercises/anagram/package.yaml +0 -3
- data/tracks/idris/config.json +3 -3
- data/tracks/kotlin/config.json +207 -43
- data/tracks/lfe/config.json +152 -32
- data/tracks/lfe/docs/TESTS.md +18 -56
- data/tracks/lua/docs/ABOUT.md +9 -0
- data/tracks/mips/config.json +72 -16
- data/tracks/ocaml/config.json +6 -0
- data/tracks/ocaml/exercises/etl/.merlin +5 -0
- data/tracks/ocaml/exercises/etl/Makefile +11 -0
- data/tracks/ocaml/exercises/etl/etl.mli +2 -0
- data/tracks/ocaml/exercises/etl/example.ml +7 -0
- data/tracks/ocaml/exercises/etl/test.ml +35 -0
- data/tracks/ocaml/exercises/raindrops/test.ml +1 -1
- data/tracks/php/config.json +7 -1
- data/tracks/php/exercises/acronym/acronym_test.php +56 -0
- data/tracks/php/exercises/acronym/example.php +20 -0
- data/tracks/racket/config.json +109 -22
- data/tracks/ruby/README.md +3 -3
- data/tracks/ruby/bin/generate +16 -0
- data/tracks/ruby/exercises/alphametics/.version +1 -1
- data/tracks/ruby/exercises/alphametics/alphametics_test.rb +24 -22
- data/tracks/ruby/exercises/alphametics/example.rb +1 -1
- data/tracks/ruby/lib/bracket_push_cases.rb +3 -3
- data/tracks/ruby/lib/{raindrop_cases.rb → raindrops_cases.rb} +1 -1
- data/tracks/rust/config.json +1 -0
- data/tracks/rust/exercises/atbash-cipher/Cargo.lock +4 -0
- data/tracks/rust/exercises/atbash-cipher/Cargo.toml +3 -0
- data/tracks/rust/exercises/atbash-cipher/example.rs +36 -0
- data/tracks/rust/exercises/atbash-cipher/tests/atbash-cipher.rs +82 -0
- data/tracks/rust/problems.md +1 -0
- data/tracks/scala/config.json +8 -0
- data/tracks/scala/exercises/sum-of-multiples/build.sbt +3 -0
- data/tracks/scala/exercises/sum-of-multiples/example.scala +10 -0
- data/tracks/scala/exercises/sum-of-multiples/src/main/scala/.keep +0 -0
- data/tracks/scala/exercises/sum-of-multiples/src/test/scala/SumOfMultiplesTest.scala +62 -0
- metadata +43 -23
- data/tracks/ruby/bin/generate-acronym +0 -7
- data/tracks/ruby/bin/generate-alphametics +0 -8
- data/tracks/ruby/bin/generate-binary +0 -7
- data/tracks/ruby/bin/generate-bracket-push +0 -7
- data/tracks/ruby/bin/generate-clock +0 -7
- data/tracks/ruby/bin/generate-connect +0 -7
- data/tracks/ruby/bin/generate-custom-set +0 -7
- data/tracks/ruby/bin/generate-difference-of-squares +0 -7
- data/tracks/ruby/bin/generate-gigasecond +0 -7
- data/tracks/ruby/bin/generate-hamming +0 -7
- data/tracks/ruby/bin/generate-hello-world +0 -7
- data/tracks/ruby/bin/generate-largest-series-product +0 -7
- data/tracks/ruby/bin/generate-leap +0 -7
- data/tracks/ruby/bin/generate-nth-prime +0 -7
- data/tracks/ruby/bin/generate-pangram +0 -7
- data/tracks/ruby/bin/generate-raindrops +0 -7
- data/tracks/ruby/bin/generate-rna-transcription +0 -7
- data/tracks/ruby/bin/generate-roman-numerals +0 -7
- data/tracks/ruby/bin/generate-run-length-encoding +0 -7
- data/tracks/ruby/bin/generate-two-bucket +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9afe3a2389f45df29805ba631f6e4c4afc5c66ef
|
4
|
+
data.tar.gz: bebab04f762c5ee338b0e5a4d645985db6b5034b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 744116cb977fbed40d585e95a734cedf12e60c2277a703826e39e74e4525881333fed0ca7e4cc3d3add5432df76b6a681bf2c12c3ae7f2223c0bb83313cfd6fd
|
7
|
+
data.tar.gz: 3932ddf8a13ac14ab7e0c0c4baaccb9cf15f7e0b4278d3411c34c07523dae0d07ff397d474a2c0e2904c71b6add9887d8c4f30d6882b6839dd1824f007c91688
|
data/CHANGELOG.md
CHANGED
data/bin/bump-content
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
system("bin/update")
|
4
|
+
|
5
|
+
file = File.absolute_path("../../lib/trackler/version.rb", __FILE__)
|
6
|
+
|
7
|
+
contents = File.read(file)
|
8
|
+
major, minor, patch, data = contents[/\ \ VERSION\ =\ "(.*)"/, 1].split(".")
|
9
|
+
|
10
|
+
version = [major, minor, patch, data.to_i + 1].join(".")
|
11
|
+
|
12
|
+
template = <<-TEMPLATE % version
|
13
|
+
module Trackler
|
14
|
+
VERSION = "%s"
|
15
|
+
end
|
16
|
+
TEMPLATE
|
17
|
+
|
18
|
+
File.open(file, "w") do |f|
|
19
|
+
f.puts template
|
20
|
+
end
|
21
|
+
|
22
|
+
cmds = [
|
23
|
+
"git add lib/trackler/version.rb",
|
24
|
+
"git commit -m 'Bump to v%s'" % version,
|
25
|
+
"git tag v%s" % version,
|
26
|
+
"git push origin master",
|
27
|
+
"git push --tags",
|
28
|
+
"gem build trackler.gemspec",
|
29
|
+
"gem install --local trackler-%s.gem" % version,
|
30
|
+
"gem push trackler-%s.gem" % version,
|
31
|
+
].each do |cmd|
|
32
|
+
system cmd
|
33
|
+
end
|
@@ -1,117 +1,118 @@
|
|
1
1
|
{
|
2
2
|
"#": [
|
3
|
-
"
|
4
|
-
"
|
5
|
-
"game
|
3
|
+
"Students should implement roll and score methods.",
|
4
|
+
"Roll should accept a single integer.",
|
5
|
+
"Score should return the game's final score, when possible",
|
6
|
+
"For brevity the tests display all the rolls in an array;",
|
7
|
+
"each element of the rolls array should be passed to the roll method",
|
8
|
+
"The final tests define situations where the score can not be returned",
|
9
|
+
"The expection for these tests is -1, indicating an error",
|
10
|
+
"In these cases you should expect an error as is idiomatic for your language",
|
11
|
+
"When to error is also left up to your implementation. There are two options",
|
12
|
+
" - Error as soon as an invalid roll is made",
|
13
|
+
" - Error when scoring a game with an invalid roll",
|
14
|
+
"You can also error in both cases."
|
6
15
|
],
|
7
|
-
"methods": {
|
8
|
-
"description": [
|
9
|
-
"Check the public API is correct."
|
10
|
-
],
|
11
|
-
"cases": [{
|
12
|
-
"description": "must be able to roll with a number of pins",
|
13
|
-
"method": "roll",
|
14
|
-
"arity": 1
|
15
|
-
}, {
|
16
|
-
"description": "must have a score",
|
17
|
-
"method": "score",
|
18
|
-
"arity": 0
|
19
|
-
}]
|
20
|
-
},
|
21
16
|
"score": {
|
22
17
|
"description": [
|
23
|
-
"
|
18
|
+
"Returns the final score of a bowling game"
|
24
19
|
],
|
25
20
|
"cases": [{
|
26
|
-
"description": "should be able to score
|
27
|
-
"rolls": [3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
28
|
-
"expected": 7
|
29
|
-
}, {
|
30
|
-
"description": "should be able to score multiple frames",
|
31
|
-
"rolls": [3, 4, 2, 3, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
32
|
-
"expected": 19
|
33
|
-
}, {
|
34
|
-
"description": "should be able to score a game with all gutterballs",
|
21
|
+
"description": "should be able to score a game with all zeros",
|
35
22
|
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
36
23
|
"expected": 0
|
37
24
|
}, {
|
38
|
-
"description": "should be able to score a game with
|
39
|
-
"rolls": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
40
|
-
"expected": 20
|
41
|
-
}, {
|
42
|
-
"description": "should be able to score a game with all open frames",
|
25
|
+
"description": "should be able to score a game with no strikes or spares",
|
43
26
|
"rolls": [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6],
|
44
27
|
"expected": 90
|
45
28
|
}, {
|
46
|
-
"description": "
|
29
|
+
"description": "a spare followed by zeros is worth ten points",
|
30
|
+
"rolls": [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
31
|
+
"expected": 10
|
32
|
+
}, {
|
33
|
+
"description": "points scored in the roll after a spare are counted twice",
|
34
|
+
"rolls": [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
35
|
+
"expected": 16
|
36
|
+
}, {
|
37
|
+
"description": "consecutive spares each get a one roll bonus",
|
38
|
+
"rolls": [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
39
|
+
"expected": 31
|
40
|
+
}, {
|
41
|
+
"description": "a spare in the last frame gets a one roll bonus that is counted once",
|
42
|
+
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7],
|
43
|
+
"expected": 17
|
44
|
+
}, {
|
45
|
+
"description": "a strike earns ten points in frame with a single roll",
|
46
|
+
"rolls": [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
47
|
+
"expected": 10
|
48
|
+
}, {
|
49
|
+
"description": "points scored in the two rolls after a strike are counted twice as a bonus",
|
47
50
|
"rolls": [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
48
51
|
"expected": 26
|
49
52
|
}, {
|
50
|
-
"description": "
|
51
|
-
"rolls": [5, 5, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
52
|
-
"expected": 20
|
53
|
-
}, {
|
54
|
-
"description": "should be able to score multiple strikes in a row",
|
53
|
+
"description": "consecutive strikes each get the two roll bonus",
|
55
54
|
"rolls": [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
56
55
|
"expected": 81
|
57
56
|
}, {
|
58
|
-
"description": "
|
59
|
-
"rolls": [5, 5, 3, 7, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
60
|
-
"expected": 32
|
61
|
-
}, {
|
62
|
-
"description": "should allow fill balls when the last frame is a strike",
|
57
|
+
"description": "a strike in the last frame gets a two roll bonus that is counted once",
|
63
58
|
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1],
|
64
59
|
"expected": 18
|
65
60
|
}, {
|
66
|
-
"description": "
|
67
|
-
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
68
|
-
"expected":
|
61
|
+
"description": "rolling a spare with the two roll bonus does not get a bonus roll",
|
62
|
+
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3],
|
63
|
+
"expected": 20
|
69
64
|
}, {
|
70
|
-
"description": "
|
65
|
+
"description": "strikes with the two roll bonus do not get bonus rolls",
|
71
66
|
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10],
|
72
67
|
"expected": 30
|
73
68
|
}, {
|
74
|
-
"description": "
|
69
|
+
"description": "a strike with the one roll bonus after a spare in the last frame does not get a bonus",
|
70
|
+
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10],
|
71
|
+
"expected": 20
|
72
|
+
}, {
|
73
|
+
"description": "all strikes is a perfect game",
|
75
74
|
"rolls": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
76
75
|
"expected": 300
|
77
|
-
}]
|
78
|
-
},
|
79
|
-
"validations": {
|
80
|
-
"description": [
|
81
|
-
"Check game rules."
|
82
|
-
],
|
83
|
-
"cases": [{
|
84
|
-
"description": "should not allow rolls with negative pins",
|
85
|
-
"rolls": [-1],
|
86
|
-
"expected": "Pins must have a value from 0 to 10"
|
87
76
|
}, {
|
88
|
-
"description": "
|
89
|
-
"rolls": [
|
90
|
-
"expected":
|
77
|
+
"description": "Rolls can not score negative points",
|
78
|
+
"rolls": [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
79
|
+
"expected": -1
|
91
80
|
}, {
|
92
|
-
"description": "
|
93
|
-
"rolls": [
|
94
|
-
"expected":
|
81
|
+
"description": "A roll can not score more than 10 points",
|
82
|
+
"rolls": [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
83
|
+
"expected": -1
|
95
84
|
}, {
|
96
|
-
"description": "
|
97
|
-
"rolls": [
|
98
|
-
"expected":
|
85
|
+
"description": "Two rolls in a frame can not score more than 10 points",
|
86
|
+
"rolls": [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
87
|
+
"expected": -1
|
99
88
|
}, {
|
100
|
-
"description": "
|
89
|
+
"description": "Two bonus rolls after a strike in the last frame can not score more than 10 points",
|
90
|
+
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6],
|
91
|
+
"expected": -1
|
92
|
+
}, {
|
93
|
+
"description": "An unstarted game can not be scored",
|
101
94
|
"rolls": [],
|
102
|
-
"expected":
|
95
|
+
"expected": -1
|
103
96
|
}, {
|
104
|
-
"description": "
|
105
|
-
"rolls": [0, 0
|
106
|
-
"expected":
|
97
|
+
"description": "An incomplete game can not be scored",
|
98
|
+
"rolls": [0, 0],
|
99
|
+
"expected": -1
|
107
100
|
}, {
|
108
|
-
"description": "
|
101
|
+
"description": "A game with more than ten frames can not be scored",
|
109
102
|
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
110
|
-
"expected":
|
103
|
+
"expected": -1
|
104
|
+
}, {
|
105
|
+
"description": "bonus rolls for a strike in the last frame must be rolled before score can be calculated",
|
106
|
+
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
|
107
|
+
"expected": -1
|
108
|
+
}, {
|
109
|
+
"description": "both bonus rolls for a strike in the last frame must be rolled before score can be calculated",
|
110
|
+
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10],
|
111
|
+
"expected": -1
|
111
112
|
}, {
|
112
|
-
"description": "
|
113
|
-
"rolls": [
|
114
|
-
"expected":
|
113
|
+
"description": "bonus roll for a spare in the last frame must be rolled before score can be calculated",
|
114
|
+
"rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3],
|
115
|
+
"expected": -1
|
115
116
|
}]
|
116
117
|
}
|
117
118
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
**NOTE: This exercise has been deprecated.**
|
@@ -0,0 +1 @@
|
|
1
|
+
**NOTE: This exercise has been deprecated.**
|
@@ -0,0 +1,83 @@
|
|
1
|
+
{
|
2
|
+
"#": [
|
3
|
+
"Here -1 is used as expected value to indicate that the",
|
4
|
+
"input value is out of the range described in the exercise."
|
5
|
+
],
|
6
|
+
"cases": [
|
7
|
+
{
|
8
|
+
"description": "zero",
|
9
|
+
"input": 0,
|
10
|
+
"expected": "zero"
|
11
|
+
},
|
12
|
+
{
|
13
|
+
"description": "one",
|
14
|
+
"input": 1,
|
15
|
+
"expected": "one"
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"description": "fourteen",
|
19
|
+
"input": 14,
|
20
|
+
"expected": "fourteen"
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"description": "twenty",
|
24
|
+
"input": 20,
|
25
|
+
"expected": "twenty"
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"description": "twenty-two",
|
29
|
+
"input": 22,
|
30
|
+
"expected": "twenty-two"
|
31
|
+
},
|
32
|
+
{
|
33
|
+
"description": "one hundred",
|
34
|
+
"input": 100,
|
35
|
+
"expected": "one hundred"
|
36
|
+
},
|
37
|
+
{
|
38
|
+
"description": "one hundred twenty-three",
|
39
|
+
"input": 123,
|
40
|
+
"expected": "one hundred twenty-three"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"description": "one thousand",
|
44
|
+
"input": 1000,
|
45
|
+
"expected": "one thousand"
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"description": "one thousand two hundred thirty-four",
|
49
|
+
"input": 1234,
|
50
|
+
"expected": "one thousand two hundred thirty-four"
|
51
|
+
},
|
52
|
+
{
|
53
|
+
"description": "one million",
|
54
|
+
"input": 1000000,
|
55
|
+
"expected": "one million"
|
56
|
+
},
|
57
|
+
{
|
58
|
+
"description": "one million two thousand three hundred forty-five",
|
59
|
+
"input": 1002345,
|
60
|
+
"expected": "one million two thousand three hundred forty-five"
|
61
|
+
},
|
62
|
+
{
|
63
|
+
"description": "one billion",
|
64
|
+
"input": 1000000000,
|
65
|
+
"expected": "one billion"
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"description": "a big number",
|
69
|
+
"input": 987654321123,
|
70
|
+
"expected": "nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three"
|
71
|
+
},
|
72
|
+
{
|
73
|
+
"description": "numbers below zero are out of range",
|
74
|
+
"input": -1,
|
75
|
+
"expected": -1
|
76
|
+
},
|
77
|
+
{
|
78
|
+
"description": "numbers above 999,999,999,999 are out of range",
|
79
|
+
"input": 1000000000000,
|
80
|
+
"expected": -1
|
81
|
+
}
|
82
|
+
]
|
83
|
+
}
|
@@ -13,22 +13,42 @@
|
|
13
13
|
{
|
14
14
|
"description": "multiple occurrences of a word",
|
15
15
|
"input": "one fish two fish red fish blue fish",
|
16
|
-
"expected": { "one"
|
16
|
+
"expected": { "one": 1, "fish": 4, "two": 1, "red": 1, "blue": 1 }
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"description": "handles cramped lists",
|
20
|
+
"input": "one,two,three",
|
21
|
+
"expected": { "one": 1, "two": 1, "three": 1 }
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"description": "handles expanded lists",
|
25
|
+
"input": "one,\ntwo,\nthree",
|
26
|
+
"expected": { "one": 1, "two": 1, "three": 1 }
|
17
27
|
},
|
18
28
|
{
|
19
29
|
"description": "ignore punctuation",
|
20
|
-
"input": "car
|
21
|
-
"expected": { "car"
|
30
|
+
"input": "car: carpet as java: javascript!!&@$%^&",
|
31
|
+
"expected": { "car": 1, "carpet": 1, "as": 1, "java": 1, "javascript": 1 }
|
22
32
|
},
|
23
33
|
{
|
24
34
|
"description": "include numbers",
|
25
35
|
"input": "testing, 1, 2 testing",
|
26
|
-
"expected": { "testing"
|
36
|
+
"expected": { "testing": 2, "1": 1, "2": 1 }
|
27
37
|
},
|
28
38
|
{
|
29
39
|
"description": "normalize case",
|
30
40
|
"input": "go Go GO Stop stop",
|
31
|
-
"expected": { "go"
|
41
|
+
"expected": { "go": 3, "stop": 2 }
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"description": "with apostrophes",
|
45
|
+
"input": "First: don't laugh. Then: don't cry.",
|
46
|
+
"expected": { "first": 1, "don't": 2, "laugh": 1, "then": 1, "cry": 1 }
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"description": "with_quotations",
|
50
|
+
"input": "Joe can't tell between 'large' and large.",
|
51
|
+
"expected": { "joe": 1, "can't": 1, "tell": 1, "between": 1, "large": 2, "and": 1 }
|
32
52
|
}
|
33
53
|
]
|
34
54
|
}
|
data/lib/trackler/version.rb
CHANGED
data/tracks/c/config.json
CHANGED
@@ -13,6 +13,7 @@
|
|
13
13
|
"raindrops",
|
14
14
|
"bob",
|
15
15
|
"grains",
|
16
|
+
"largest-series-product",
|
16
17
|
"pangram",
|
17
18
|
"nth-prime",
|
18
19
|
"beer-song",
|
@@ -81,6 +82,14 @@
|
|
81
82
|
"bitwise operations",
|
82
83
|
"performance optimizations"
|
83
84
|
]
|
85
|
+
}, {
|
86
|
+
"difficulty": 5,
|
87
|
+
"slug": "largest-series-product",
|
88
|
+
"topics": [
|
89
|
+
"control-flow (loops)",
|
90
|
+
"strings",
|
91
|
+
"performance optimizations"
|
92
|
+
]
|
84
93
|
}, {
|
85
94
|
"difficulty": 3,
|
86
95
|
"slug": "pangram",
|
@@ -0,0 +1,16 @@
|
|
1
|
+
CFLAGS = -std=c99
|
2
|
+
CFLAGS += -Wall
|
3
|
+
CFLAGS += -Wextra
|
4
|
+
CFLAGS += -pedantic
|
5
|
+
CFLAGS += -Werror
|
6
|
+
|
7
|
+
|
8
|
+
test: tests.out
|
9
|
+
@./tests.out
|
10
|
+
|
11
|
+
clean:
|
12
|
+
rm -f *.o *.out
|
13
|
+
|
14
|
+
tests.out: test/test_largest_series_product.c src/largest_series_product.c src/largest_series_product.h
|
15
|
+
@echo Compiling $@
|
16
|
+
@cc $(CFLAGS) src/largest_series_product.c test/vendor/unity.c test/test_largest_series_product.c -o tests.out
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#include <string.h>
|
2
|
+
#include <stdbool.h>
|
3
|
+
#include "largest_series_product.h"
|
4
|
+
|
5
|
+
#define MAX(x, y) (x) > (y) ? (x) : (y)
|
6
|
+
|
7
|
+
static int to_int(char c)
|
8
|
+
{
|
9
|
+
return c - '0';
|
10
|
+
}
|
11
|
+
|
12
|
+
static bool is_digit(char c)
|
13
|
+
{
|
14
|
+
return (c >= '0') && (c <= '9');
|
15
|
+
}
|
16
|
+
|
17
|
+
int64_t largest_series_product(char *digits, size_t span)
|
18
|
+
{
|
19
|
+
size_t digit_count = strlen(digits);
|
20
|
+
size_t zeros = 0;
|
21
|
+
long product = 1;
|
22
|
+
long largest_product = 0;
|
23
|
+
|
24
|
+
if (span > digit_count)
|
25
|
+
return -1;
|
26
|
+
|
27
|
+
if (!span && !digit_count)
|
28
|
+
return 1;
|
29
|
+
|
30
|
+
for (size_t i = 0; i < digit_count; i++) {
|
31
|
+
if (!is_digit(digits[i]))
|
32
|
+
return -1;
|
33
|
+
|
34
|
+
int to_add = to_int(digits[i]);
|
35
|
+
|
36
|
+
if (i >= span) {
|
37
|
+
int to_remove = to_int(digits[i - span]);
|
38
|
+
if (to_remove == 0)
|
39
|
+
zeros--;
|
40
|
+
else
|
41
|
+
product /= to_remove;
|
42
|
+
}
|
43
|
+
|
44
|
+
if (to_add > 0)
|
45
|
+
product *= to_add;
|
46
|
+
else
|
47
|
+
zeros++;
|
48
|
+
|
49
|
+
if ((i + 1 >= span) && (zeros == 0))
|
50
|
+
largest_product = MAX(largest_product, product);
|
51
|
+
}
|
52
|
+
|
53
|
+
return largest_product;
|
54
|
+
}
|
@@ -0,0 +1,114 @@
|
|
1
|
+
#include "vendor/unity.h"
|
2
|
+
#include "../src/largest_series_product.h"
|
3
|
+
|
4
|
+
void test_can_find_the_largest_product_of_2_with_numbers_in_order(void)
|
5
|
+
{
|
6
|
+
TEST_ASSERT_EQUAL(72, largest_series_product("0123456789", 2));
|
7
|
+
}
|
8
|
+
|
9
|
+
void test_can_find_the_largest_product_of_2(void)
|
10
|
+
{
|
11
|
+
TEST_ASSERT_EQUAL(48, largest_series_product("576802143", 2));
|
12
|
+
}
|
13
|
+
|
14
|
+
void test_finds_the_largest_product_if_span_equals_length(void)
|
15
|
+
{
|
16
|
+
TEST_ASSERT_EQUAL(18, largest_series_product("29", 2));
|
17
|
+
}
|
18
|
+
|
19
|
+
void test_can_find_the_largest_product_of_3_with_numbers_in_order(void)
|
20
|
+
{
|
21
|
+
TEST_ASSERT_EQUAL(504, largest_series_product("0123456789", 3));
|
22
|
+
}
|
23
|
+
|
24
|
+
void test_can_find_the_largest_product_of_3(void)
|
25
|
+
{
|
26
|
+
TEST_ASSERT_EQUAL(270, largest_series_product("1027839564", 3));
|
27
|
+
}
|
28
|
+
|
29
|
+
void test_can_find_the_largest_product_of_5_with_numbers_in_order(void)
|
30
|
+
{
|
31
|
+
TEST_ASSERT_EQUAL(15120, largest_series_product("0123456789", 5));
|
32
|
+
}
|
33
|
+
|
34
|
+
void test_can_get_the_largest_product_of_a_big_number(void)
|
35
|
+
{
|
36
|
+
TEST_ASSERT_EQUAL(23520,
|
37
|
+
largest_series_product
|
38
|
+
("73167176531330624919225119674426574742355349194934", 6));
|
39
|
+
}
|
40
|
+
|
41
|
+
void test_can_get_the_largest_product_of_a_big_number_ii(void)
|
42
|
+
{
|
43
|
+
TEST_ASSERT_EQUAL(28350,
|
44
|
+
largest_series_product
|
45
|
+
("52677741234314237566414902593461595376319419139427", 6));
|
46
|
+
}
|
47
|
+
|
48
|
+
void test_can_get_the_largest_product_of_a_big_number_project_euler(void)
|
49
|
+
{
|
50
|
+
TEST_ASSERT_EQUAL_INT64(23514624000,
|
51
|
+
largest_series_product
|
52
|
+
("7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450",
|
53
|
+
13));
|
54
|
+
}
|
55
|
+
|
56
|
+
void test_reports_zero_if_the_only_digits_are_zero(void)
|
57
|
+
{
|
58
|
+
TEST_ASSERT_EQUAL(0, largest_series_product("0000", 2));
|
59
|
+
}
|
60
|
+
|
61
|
+
void test_reports_zero_if_all_spans_include_zero(void)
|
62
|
+
{
|
63
|
+
TEST_ASSERT_EQUAL(0, largest_series_product("99099", 3));
|
64
|
+
}
|
65
|
+
|
66
|
+
void test_rejects_span_longer_than_string_length(void)
|
67
|
+
{
|
68
|
+
TEST_ASSERT_EQUAL(-1, largest_series_product("123", 4));
|
69
|
+
}
|
70
|
+
|
71
|
+
void test_reports_1_for_empty_string_and_empty_product_(void)
|
72
|
+
{
|
73
|
+
TEST_ASSERT_EQUAL(1, largest_series_product("", 0));
|
74
|
+
}
|
75
|
+
|
76
|
+
void test_reports_1_for_nonempty_string_and_empty_product_(void)
|
77
|
+
{
|
78
|
+
TEST_ASSERT_EQUAL(1, largest_series_product("123", 0));
|
79
|
+
}
|
80
|
+
|
81
|
+
void test_rejects_empty_string_and_nonzero_span(void)
|
82
|
+
{
|
83
|
+
TEST_ASSERT_EQUAL(-1, largest_series_product("", 1));
|
84
|
+
}
|
85
|
+
|
86
|
+
void test_rejects_invalid_character_in_digits(void)
|
87
|
+
{
|
88
|
+
TEST_ASSERT_EQUAL(-1, largest_series_product("123a5", 2));
|
89
|
+
}
|
90
|
+
|
91
|
+
int main(void)
|
92
|
+
{
|
93
|
+
UnityBegin("largest_series_product.c");
|
94
|
+
|
95
|
+
RUN_TEST(test_can_find_the_largest_product_of_2_with_numbers_in_order);
|
96
|
+
RUN_TEST(test_can_find_the_largest_product_of_2);
|
97
|
+
RUN_TEST(test_finds_the_largest_product_if_span_equals_length);
|
98
|
+
RUN_TEST(test_can_find_the_largest_product_of_3_with_numbers_in_order);
|
99
|
+
RUN_TEST(test_can_find_the_largest_product_of_3);
|
100
|
+
RUN_TEST(test_can_find_the_largest_product_of_5_with_numbers_in_order);
|
101
|
+
RUN_TEST(test_can_get_the_largest_product_of_a_big_number);
|
102
|
+
RUN_TEST(test_can_get_the_largest_product_of_a_big_number_ii);
|
103
|
+
RUN_TEST(test_can_get_the_largest_product_of_a_big_number_project_euler);
|
104
|
+
RUN_TEST(test_reports_zero_if_the_only_digits_are_zero);
|
105
|
+
RUN_TEST(test_reports_zero_if_all_spans_include_zero);
|
106
|
+
RUN_TEST(test_rejects_span_longer_than_string_length);
|
107
|
+
RUN_TEST(test_reports_1_for_empty_string_and_empty_product_);
|
108
|
+
RUN_TEST(test_reports_1_for_nonempty_string_and_empty_product_);
|
109
|
+
RUN_TEST(test_rejects_empty_string_and_nonzero_span);
|
110
|
+
RUN_TEST(test_rejects_invalid_character_in_digits);
|
111
|
+
|
112
|
+
UnityEnd();
|
113
|
+
return 0;
|
114
|
+
}
|