trackler 2.0.3.8 → 2.0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/common/exercises/book-store/description.md +67 -0
- data/common/exercises/book-store/metadata.yml +4 -0
- data/lib/trackler/version.rb +1 -1
- data/tracks/crystal/exercises/difference-of-squares/src/difference_of_squares.cr +1 -0
- data/tracks/ecmascript/exercises/custom-set/package.json +1 -0
- data/tracks/ecmascript/exercises/palindrome-products/palindrome-products.js +18 -18
- data/tracks/fsharp/docs/INSTALLATION.md +2 -3
- data/tracks/fsharp/docs/TESTS.md +1 -1
- data/tracks/fsharp/exercises/accumulate/HINTS.md +3 -0
- data/tracks/fsharp/exercises/diamond/HINTS.md +2 -0
- data/tracks/fsharp/exercises/grains/HINTS.md +1 -1
- data/tracks/fsharp/exercises/hello-world/HINTS.md +1 -1
- data/tracks/fsharp/exercises/parallel-letter-frequency/HINTS.md +3 -0
- data/tracks/fsharp/exercises/poker/HINTS.md +2 -0
- data/tracks/fsharp/exercises/raindrops/HINTS.md +2 -0
- data/tracks/fsharp/exercises/space-age/HINTS.md +3 -0
- data/tracks/javascript/exercises/bowling/bowling.spec.js +83 -63
- data/tracks/ocaml/config.json +5 -0
- data/tracks/ocaml/exercises/leap/test.ml +7 -13
- data/tracks/ocaml/exercises/robot-name/.merlin +3 -0
- data/tracks/ocaml/exercises/robot-name/Makefile +11 -0
- data/tracks/ocaml/exercises/robot-name/example.ml +26 -0
- data/tracks/ocaml/exercises/robot-name/robot_name.mli +7 -0
- data/tracks/ocaml/exercises/robot-name/test.ml +64 -0
- data/tracks/ocaml/tools/test-generator/Makefile +3 -0
- data/tracks/ocaml/tools/test-generator/README.md +1 -0
- data/tracks/ocaml/tools/test-generator/src/canonical_data_checker.ml +23 -0
- data/tracks/ocaml/tools/test-generator/src/controller.ml +12 -0
- data/tracks/ocaml/tools/test-generator/src/parser.ml +29 -22
- data/tracks/ocaml/tools/test-generator/src/utils.ml +8 -0
- data/tracks/ocaml/tools/test-generator/test/clock.json +437 -0
- data/tracks/ocaml/tools/test-generator/test/parser_test.ml +18 -4
- data/tracks/ocaml/tools/test-generator/test/with-methods-key.json +22 -0
- data/tracks/perl6/config.json +5 -0
- data/tracks/perl6/exercises/wordy/Example.p6 +16 -0
- data/tracks/perl6/exercises/wordy/cases.json +89 -0
- data/tracks/perl6/exercises/wordy/wordy.t +29 -0
- data/tracks/ruby/exercises/acronym/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/alphametics/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/anagram/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/binary/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/bowling/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/bracket-push/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/clock/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/connect/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/custom-set/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/difference-of-squares/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/dominoes/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/gigasecond/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/hamming/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/hello-world/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/isogram/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/largest-series-product/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/leap/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/nth-prime/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/pangram/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/queen-attack/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/raindrops/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/rna-transcription/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/roman-numerals/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/run-length-encoding/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/sieve/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/tournament/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/transpose/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/triangle/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/two-bucket/{.version → .meta/.version} +0 -0
- data/tracks/ruby/exercises/word-count/{.version → .meta/.version} +0 -0
- data/tracks/ruby/lib/generator.rb +15 -4
- data/tracks/rust/config.json +1 -0
- data/tracks/rust/exercises/largest-series-product/.gitignore +7 -0
- data/tracks/rust/exercises/largest-series-product/Cargo.toml +3 -0
- data/tracks/rust/exercises/largest-series-product/HINTS.md +6 -0
- data/tracks/rust/exercises/largest-series-product/example.rs +22 -0
- data/tracks/rust/exercises/largest-series-product/tests/largest-series-product.rs +105 -0
- data/tracks/rust/problems.md +1 -0
- data/tracks/scala/.gitignore +1 -0
- data/tracks/scala/exercises/accumulate/src/test/scala/{accumulate_test.scala → AccumulateTest.scala} +0 -0
- data/tracks/scala/exercises/allergies/src/test/scala/{allergies_test.scala → AllergiesTest.scala} +0 -0
- data/tracks/scala/exercises/anagram/src/test/scala/{anagram_test.scala → AnagramTest.scala} +0 -0
- data/tracks/scala/exercises/binary/src/test/scala/{binary_test.scala → BinaryTest.scala} +0 -0
- data/tracks/scala/exercises/bob/src/test/scala/{bob_test.scala → BobTest.scala} +0 -0
- data/tracks/scala/exercises/difference-of-squares/src/test/scala/{squares_test.scala → SquaresTest.scala} +0 -0
- data/tracks/scala/exercises/etl/src/test/scala/{etl_test.scala → EtlTest.scala} +0 -0
- data/tracks/scala/exercises/gigasecond/src/test/scala/{gigasecond_test.scala → GigasecondTest.scala} +0 -0
- data/tracks/scala/exercises/grade-school/src/test/scala/{grade_school_test.scala → GradeSchoolTest.scala} +0 -0
- data/tracks/scala/exercises/grains/src/test/scala/{grains_test.scala → GrainsTest.scala} +0 -0
- data/tracks/scala/exercises/hamming/src/test/scala/{hamming_test.scala → HammingTest.scala} +0 -0
- data/tracks/scala/exercises/hello-world/src/test/scala/HelloWorldTest.scala +2 -0
- data/tracks/scala/exercises/leap/src/test/scala/{leap_test.scala → LeapTest.scala} +0 -0
- data/tracks/scala/exercises/meetup/src/test/scala/{meetup_test.scala → MeetupTest.scala} +0 -0
- data/tracks/scala/exercises/nth-prime/example.scala +3 -1
- data/tracks/scala/exercises/nth-prime/src/test/scala/PrimeTest.scala +11 -6
- data/tracks/scala/exercises/nucleotide-count/src/test/scala/{nucleotide_count_test.scala → NucleotideCountTest.scala} +0 -0
- data/tracks/scala/exercises/palindrome-products/src/test/scala/PalindromeProductsTest.scala +7 -0
- data/tracks/scala/exercises/pangram/src/test/scala/{PangramsTest.scala → PangramTest.scala} +0 -0
- data/tracks/scala/exercises/parallel-letter-frequency/HINTS.md +26 -0
- data/tracks/scala/exercises/phone-number/src/test/scala/{phone_number_test.scala → PhoneNumberTest.scala} +0 -0
- data/tracks/scala/exercises/prime-factors/src/test/scala/{primefactors_test.scala → PrimefactorsTest.scala} +10 -0
- data/tracks/scala/exercises/raindrops/src/test/scala/{raindrops_test.scala → RaindropsTest.scala} +15 -0
- data/tracks/scala/exercises/rna-transcription/src/test/scala/{transcription_test.scala → RnaTranscriptionTest.scala} +8 -0
- data/tracks/scala/exercises/robot-name/src/test/scala/{robot_name_test.scala → RobotNameTest.scala} +0 -0
- data/tracks/scala/exercises/roman-numerals/src/test/scala/{roman_numerals_test.scala → RomanNumeralsTest.scala} +17 -0
- data/tracks/scala/exercises/saddle-points/src/test/scala/{SaddlePointsSpecs.scala → SaddlePointsTest.scala} +3 -0
- data/tracks/scala/exercises/scrabble-score/src/test/scala/{scrabble_score_test.scala → ScrabbleScoreTest.scala} +0 -0
- data/tracks/scala/exercises/sgf-parsing/src/test/scala/SgfTest.scala +1 -0
- data/tracks/scala/exercises/space-age/src/test/scala/{space_age_test.scala → SpaceAgeTest.scala} +0 -0
- data/tracks/scala/exercises/sublist/src/test/scala/{sublist_test.scala → SublistTest.scala} +0 -0
- data/tracks/scala/exercises/triangle/src/test/scala/{triangle_test.scala → TriangleTest.scala} +7 -0
- data/tracks/scala/exercises/word-count/src/test/scala/{word_count_test.scala → WordCountTest.scala} +0 -0
- data/tracks/scala/exercises/zipper/src/test/scala/ZipperTest.scala +7 -0
- data/tracks/swift/config.json +19 -0
- data/tracks/swift/docs/TESTS.md +114 -23
- data/tracks/swift/exercises/beer-song/BeerSongExample.swift +32 -0
- data/tracks/swift/exercises/beer-song/BeerSongTest.swift +44 -0
- data/tracks/swift/exercises/hello-world/{helloWorldExample.swift → HelloWorldExample.swift} +4 -0
- data/tracks/swift/exercises/hello-world/{helloWorldTest/helloWorldTest.swift → helloWorldTest.swift} +1 -1
- data/tracks/swift/exercises/sublist/SubListTest.swift +95 -0
- data/tracks/swift/exercises/sublist/SublistExample.swift +72 -0
- data/tracks/swift/img/page_assets/001-splash.png +0 -0
- data/tracks/swift/img/page_assets/002-templateChooser.png +0 -0
- data/tracks/swift/img/page_assets/003-nameProject.jpg +0 -0
- data/tracks/swift/img/page_assets/004-saveProject.jpg +0 -0
- data/tracks/swift/img/page_assets/005-folderLayout.png +0 -0
- data/tracks/swift/img/page_assets/006-newProjectInitial.jpg +0 -0
- data/tracks/swift/img/page_assets/007-fileInspectorUpdate.png +0 -0
- data/tracks/swift/img/page_assets/008-templateChooserSwift.png +0 -0
- data/tracks/swift/img/page_assets/009-importTestSource.png +0 -0
- data/tracks/swift/img/page_assets/010-testsImportExample.png +0 -0
- data/tracks/swift/img/page_assets/011-finalLayoutExample.png +0 -0
- data/tracks/swift/xcodeProject/xSwift.xcodeproj/project.pbxproj +36 -56
- metadata +103 -65
- data/tracks/swift/exercises/hello-world/helloWorld.swift +0 -1
- data/tracks/swift/exercises/hello-world/helloWorld.xcodeproj/project.pbxproj +0 -256
- data/tracks/swift/exercises/hello-world/helloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- data/tracks/swift/exercises/hello-world/helloWorldTest/Info.plist +0 -24
|
@@ -17,7 +17,7 @@ let parser_tests = [
|
|
|
17
17
|
ae (single []) (parse_json_text "{\"cases\" : []}");
|
|
18
18
|
|
|
19
19
|
"gives an error with a json map that does not have the key cases in" >::
|
|
20
|
-
ae (Error
|
|
20
|
+
ae (Error (TestMustHaveKeyCalledCases "case"))
|
|
21
21
|
(parse_json_text "{\"case\" : [{\"description\" : \"d1\", \"expected\" : 100}]}");
|
|
22
22
|
|
|
23
23
|
"gives an error with cases that is not a json list" >::
|
|
@@ -61,15 +61,15 @@ let parser_tests = [
|
|
|
61
61
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"input\" : [\"s1\", \"s2\"], \"expected\" : 85}]}");
|
|
62
62
|
|
|
63
63
|
"an element without a description is an Error" >::
|
|
64
|
-
ae (Error
|
|
64
|
+
ae (Error NoDescription)
|
|
65
65
|
(parse_json_text "{\"cases\" : [{\"input\" : 11, \"expected\" : 85}]}");
|
|
66
66
|
|
|
67
67
|
"an element with a description which is an int is an Error" >::
|
|
68
68
|
ae (Error BadDescription)
|
|
69
69
|
(parse_json_text "{\"cases\" : [{\"description\" : 1, \"input\" : 11, \"expected\" : 85}]}");
|
|
70
70
|
|
|
71
|
-
"an element without
|
|
72
|
-
ae (Error
|
|
71
|
+
"an element without description is an Error" >::
|
|
72
|
+
ae (Error NoDescription)
|
|
73
73
|
(parse_json_text "{\"cases\" : [{\"input\" : 11}]}");
|
|
74
74
|
|
|
75
75
|
"parses a map in the expected parameter" >::(fun _ctx ->
|
|
@@ -97,4 +97,18 @@ let parser_tests = [
|
|
|
97
97
|
| Ok (Single p) -> assert_failure "was single"
|
|
98
98
|
| Error e -> assert_failure ("failed to parse difference_of_squares.json: " ^ show_error e)
|
|
99
99
|
);
|
|
100
|
+
|
|
101
|
+
"parses clock.json" >::(fun ctxt ->
|
|
102
|
+
match parse_json_text @@ In_channel.read_all "test/clock.json" with
|
|
103
|
+
| Ok (Suite p) -> assert_equal ["create"; "add"; "equal"] (List.map ~f:(fun x -> x.name) p)
|
|
104
|
+
| Ok (Single p) -> assert_failure "was single"
|
|
105
|
+
| Error e -> assert_failure ("failed to parse clock.json: " ^ show_error e)
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
"parses json with a methods key for dynamic languages" >::(fun ctxt ->
|
|
109
|
+
match parse_json_text @@ In_channel.read_all "test/with-methods-key.json" with
|
|
110
|
+
| Ok (Suite p) -> assert_failure "was suite"
|
|
111
|
+
| Ok (Single p) -> ()
|
|
112
|
+
| Error e -> assert_failure ("failed to parse with-methods-key.json: " ^ show_error e)
|
|
113
|
+
);
|
|
100
114
|
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"#": [
|
|
3
|
+
"Markdown is a shorthand for creating HTML from text strings."
|
|
4
|
+
],
|
|
5
|
+
"methods": {
|
|
6
|
+
"description": [
|
|
7
|
+
"Check the public API is correct."
|
|
8
|
+
],
|
|
9
|
+
"cases": [{
|
|
10
|
+
"description": "must be able to parse a Markdown string",
|
|
11
|
+
"method": "parse",
|
|
12
|
+
"arity": 1
|
|
13
|
+
}]
|
|
14
|
+
},
|
|
15
|
+
"cases": [
|
|
16
|
+
{
|
|
17
|
+
"description": "parses normal text as a paragraph",
|
|
18
|
+
"input": "This will be a paragraph",
|
|
19
|
+
"expected": "<p>This will be a paragraph</p>"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
data/tracks/perl6/config.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
sub answer($q is copy) is export {
|
|
2
|
+
|
|
3
|
+
given $q {
|
|
4
|
+
s:s:g/^What is|\?$//;
|
|
5
|
+
s:g/plus/+/;
|
|
6
|
+
s:g/minus/-/;
|
|
7
|
+
|
|
8
|
+
loop {
|
|
9
|
+
last unless s:s/(.*) multiplied by/($0)*/
|
|
10
|
+
or s:s,(.*) divided by,($0)/,;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
use MONKEY-SEE-NO-EVAL;
|
|
15
|
+
return EVAL $q;
|
|
16
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"#": [
|
|
3
|
+
"The tests that expect 'false' should be implemented to raise",
|
|
4
|
+
"an error, or indicate a failure. Implement this in a way that",
|
|
5
|
+
"makes sense for your language."
|
|
6
|
+
],
|
|
7
|
+
"cases": [
|
|
8
|
+
{
|
|
9
|
+
"description": "addition",
|
|
10
|
+
"input": "What is 1 plus 1?",
|
|
11
|
+
"expected": 2
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"description": "more addition",
|
|
15
|
+
"input": "What is 53 plus 2?",
|
|
16
|
+
"expected": 55
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"description": "addition with negative numbers",
|
|
20
|
+
"input": "What is -1 plus -10?",
|
|
21
|
+
"expected": -11
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"description": "large addition",
|
|
25
|
+
"input": "What is 123 plus 45678?",
|
|
26
|
+
"expected": 45801
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"description": "subtraction",
|
|
30
|
+
"input": "What is 4 minus -12?",
|
|
31
|
+
"expected": 16
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"description": "multiplication",
|
|
35
|
+
"input": "What is -3 multiplied by 25?",
|
|
36
|
+
"expected": -75
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"description": "division",
|
|
40
|
+
"input": "What is 33 divided by -3?",
|
|
41
|
+
"expected": -11
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"description": "multiple additions",
|
|
45
|
+
"input": "What is 1 plus 1 plus 1?",
|
|
46
|
+
"expected": 3
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"description": "addition and subtraction",
|
|
50
|
+
"input": "What is 1 plus 5 minus -2?",
|
|
51
|
+
"expected": 8
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"description": "multiple subtraction",
|
|
55
|
+
"input": "What is 20 minus 4 minus 13?",
|
|
56
|
+
"expected": 3
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"description": "subtraction then addition",
|
|
60
|
+
"input": "What is 17 minus 6 plus 3?",
|
|
61
|
+
"expected": 14
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"description": "multiple multiplication",
|
|
65
|
+
"input": "What is 2 multiplied by -2 multiplied by 3?",
|
|
66
|
+
"expected": -12
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"description": "addition and multiplication",
|
|
70
|
+
"input": "What is -3 plus 7 multiplied by -2?",
|
|
71
|
+
"expected": -8
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"description": "multiple division",
|
|
75
|
+
"input": "What is -12 divided by 2 divided by -3?",
|
|
76
|
+
"expected": 2
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"description": "unknown operation",
|
|
80
|
+
"input": "What is 52 cubed?",
|
|
81
|
+
"expected": null
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"description": "Non math question",
|
|
85
|
+
"input": "Who is the President of the United States?",
|
|
86
|
+
"expected": null
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env perl6
|
|
2
|
+
|
|
3
|
+
use Test;
|
|
4
|
+
use JSON::Tiny;
|
|
5
|
+
|
|
6
|
+
use lib ( my $dir = IO::Path.new($?FILE).parent ).path;
|
|
7
|
+
|
|
8
|
+
my $module_name = %*ENV<EXERCISM>.so ?? 'Example' !! 'Wordy';
|
|
9
|
+
my @potential_module = <p6 pm6 pm>.map: $module_name ~ '.' ~ *;
|
|
10
|
+
|
|
11
|
+
my $module = first { $dir.child($_).e }, |@potential_module
|
|
12
|
+
or die "No file '$module_name.p6' found\n";
|
|
13
|
+
|
|
14
|
+
require $module <&answer>;
|
|
15
|
+
|
|
16
|
+
plan 16;
|
|
17
|
+
|
|
18
|
+
my %cases = from-json $dir.child('cases.json').slurp;
|
|
19
|
+
|
|
20
|
+
for |%cases<cases> -> %case {
|
|
21
|
+
with %case<expected> {
|
|
22
|
+
is answer(%case<input>), |%case<expected description>
|
|
23
|
+
or diag 'input: ' ~ %case<input>;
|
|
24
|
+
}
|
|
25
|
+
without %case<expected> {
|
|
26
|
+
dies-ok { answer(%case<input>) }, %case<description>
|
|
27
|
+
or diag 'input: ' ~ %case<input>;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -14,20 +14,31 @@ class Generator
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def metadata_dir
|
|
17
|
-
# rubocop:disable Metrics/LineLength
|
|
18
17
|
File.expand_path(File.join('..', '..', '..', METADATA_REPOSITORY, 'exercises', name), __FILE__)
|
|
19
18
|
end
|
|
20
19
|
|
|
20
|
+
def exercise_dir
|
|
21
|
+
File.expand_path(File.join('..', '..', 'exercises', name), __FILE__)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def exercise_meta_dir
|
|
25
|
+
File.join(exercise_dir,'.meta')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def version_filename
|
|
29
|
+
File.join(exercise_meta_dir,'.version')
|
|
30
|
+
end
|
|
31
|
+
|
|
21
32
|
def data
|
|
22
33
|
File.read(File.join(metadata_dir, 'canonical-data.json'))
|
|
23
34
|
end
|
|
24
35
|
|
|
25
36
|
def path_to(file)
|
|
26
|
-
File.
|
|
37
|
+
File.join(exercise_dir,file)
|
|
27
38
|
end
|
|
28
39
|
|
|
29
40
|
def version
|
|
30
|
-
@version ||= File.read(
|
|
41
|
+
@version ||= File.read(version_filename).strip.to_i
|
|
31
42
|
end
|
|
32
43
|
|
|
33
44
|
def sha1
|
|
@@ -70,7 +81,7 @@ class Generator
|
|
|
70
81
|
end
|
|
71
82
|
|
|
72
83
|
def increment_version
|
|
73
|
-
File.open(
|
|
84
|
+
File.open(version_filename, 'w') do |f|
|
|
74
85
|
f.write version + 1
|
|
75
86
|
end
|
|
76
87
|
end
|
data/tracks/rust/config.json
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
pub fn lsp(string_digits: &str, span: usize) -> Result<u64, String> {
|
|
2
|
+
if span == 0 {
|
|
3
|
+
return Ok(1);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
if string_digits.chars().any(|c| !c.is_digit(10)) {
|
|
7
|
+
return Err(String::from("All characters must be numbers"));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let products: Vec<u64> = string_digits.chars()
|
|
11
|
+
.map(|c| c.to_digit(10).unwrap() as u64)
|
|
12
|
+
.collect::<Vec<u64>>()
|
|
13
|
+
.windows(span)
|
|
14
|
+
.map(|w| w.into_iter().product())
|
|
15
|
+
.collect();
|
|
16
|
+
|
|
17
|
+
if let Some(&x) = products.iter().max() {
|
|
18
|
+
Ok(x)
|
|
19
|
+
} else {
|
|
20
|
+
Err(String::from("Span longer than string"))
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
extern crate largest_series_product;
|
|
2
|
+
|
|
3
|
+
use largest_series_product::*;
|
|
4
|
+
|
|
5
|
+
#[test]
|
|
6
|
+
fn return_is_a_result() {
|
|
7
|
+
assert!(lsp("29", 2).is_ok());
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
#[test]
|
|
11
|
+
#[ignore]
|
|
12
|
+
fn find_the_largest_product_when_span_equals_length() {
|
|
13
|
+
assert_eq!(18, lsp("29", 2).unwrap());
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#[test]
|
|
17
|
+
#[ignore]
|
|
18
|
+
fn find_the_largest_product_of_two_with_numbers_in_order() {
|
|
19
|
+
assert_eq!(72, lsp("0123456789", 2).unwrap());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
#[test]
|
|
23
|
+
#[ignore]
|
|
24
|
+
fn find_the_largest_product_of_two_with_numbers_not_in_order() {
|
|
25
|
+
assert_eq!(48, lsp("576802143", 2).unwrap());
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#[test]
|
|
29
|
+
#[ignore]
|
|
30
|
+
fn find_the_largest_product_of_three_with_numbers_in_order() {
|
|
31
|
+
assert_eq!(504, lsp("0123456789", 3).unwrap());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#[test]
|
|
35
|
+
#[ignore]
|
|
36
|
+
fn find_the_largest_product_of_three_with_numbers_not_in_order() {
|
|
37
|
+
assert_eq!(270, lsp("1027839564", 3).unwrap());
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#[test]
|
|
41
|
+
#[ignore]
|
|
42
|
+
fn find_the_largest_product_of_five_with_numbers_in_order() {
|
|
43
|
+
assert_eq!(15120, lsp("0123456789", 5).unwrap());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#[test]
|
|
47
|
+
#[ignore]
|
|
48
|
+
fn span_of_six_in_a_large_number() {
|
|
49
|
+
assert_eq!(23520,
|
|
50
|
+
lsp("73167176531330624919225119674426574742355349194934", 6).unwrap());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#[test]
|
|
54
|
+
#[ignore]
|
|
55
|
+
fn returns_zero_if_number_is_zeros() {
|
|
56
|
+
assert_eq!(0, lsp("0000", 2).unwrap());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
#[test]
|
|
60
|
+
#[ignore]
|
|
61
|
+
fn returns_zero_if_all_products_are_zero() {
|
|
62
|
+
assert_eq!(0, lsp("99099", 3).unwrap());
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
#[test]
|
|
66
|
+
#[ignore]
|
|
67
|
+
fn a_span_is_longer_than_number_is_an_error() {
|
|
68
|
+
assert!(lsp("123", 4).is_err());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// There may be some confusion about whether this should be 1 or error.
|
|
72
|
+
// The reasoning for it being 1 is this:
|
|
73
|
+
// There is one 0-character string contained in the empty string.
|
|
74
|
+
// That's the empty string itself.
|
|
75
|
+
// The empty product is 1 (the identity for multiplication).
|
|
76
|
+
// Therefore LSP('', 0) is 1.
|
|
77
|
+
// It's NOT the case that LSP('', 0) takes max of an empty list.
|
|
78
|
+
// So there is no error.
|
|
79
|
+
// Compare against LSP('123', 4):
|
|
80
|
+
// There are zero 4-character strings in '123'.
|
|
81
|
+
// So LSP('123', 4) really DOES take the max of an empty list.
|
|
82
|
+
// So LSP('123', 4) errors and LSP('', 0) does NOT.
|
|
83
|
+
#[test]
|
|
84
|
+
#[ignore]
|
|
85
|
+
fn an_empty_string_and_no_span_returns_one() {
|
|
86
|
+
assert_eq!(1, lsp("", 0).unwrap());
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
#[test]
|
|
90
|
+
#[ignore]
|
|
91
|
+
fn a_non_empty_string_and_no_span_returns_one() {
|
|
92
|
+
assert_eq!(1, lsp("123", 0).unwrap());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#[test]
|
|
96
|
+
#[ignore]
|
|
97
|
+
fn empty_string_and_non_zero_span_is_an_error() {
|
|
98
|
+
assert!(lsp("", 1).is_err());
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
#[test]
|
|
102
|
+
#[ignore]
|
|
103
|
+
fn a_string_with_non_digits_is_an_error() {
|
|
104
|
+
assert!(lsp("1234a5", 2).is_err());
|
|
105
|
+
}
|