trackler 2.1.0.9 → 2.1.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/exercises/perfect-numbers/description.md +2 -2
- data/common/exercises/phone-number/canonical-data.json +1 -7
- data/common/exercises/tournament/canonical-data.json +96 -21
- data/common/exercises/tournament/description.md +0 -5
- data/lib/trackler/version.rb +1 -1
- data/tracks/coq/README.md +6 -8
- data/tracks/coq/exercises/hello-world/example.v +3 -0
- data/tracks/coq/exercises/hello-world/hello-world.v +3 -0
- data/tracks/coq/exercises/rna-transcription/DNA.v +4 -0
- data/tracks/coq/exercises/rna-transcription/example.v +15 -0
- data/tracks/coq/exercises/rna-transcription/rna-transcription.v +5 -0
- data/tracks/coq/exercises/tautology/description.md +1 -0
- data/tracks/coq/exercises/tautology/example.v +4 -0
- data/tracks/coq/exercises/tautology/tautology.v +4 -0
- data/tracks/haskell/exercises/accumulate/package.yaml +1 -0
- data/tracks/haskell/exercises/accumulate/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/acronym/package.yaml +1 -0
- data/tracks/haskell/exercises/acronym/test/Tests.hs +0 -5
- data/tracks/haskell/exercises/all-your-base/package.yaml +1 -0
- data/tracks/haskell/exercises/all-your-base/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/allergies/package.yaml +1 -0
- data/tracks/haskell/exercises/allergies/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/alphametics/package.yaml +1 -0
- data/tracks/haskell/exercises/alphametics/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/anagram/package.yaml +1 -0
- data/tracks/haskell/exercises/anagram/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/atbash-cipher/package.yaml +1 -0
- data/tracks/haskell/exercises/atbash-cipher/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/bank-account/package.yaml +1 -0
- data/tracks/haskell/exercises/bank-account/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/beer-song/package.yaml +1 -0
- data/tracks/haskell/exercises/binary/package.yaml +1 -0
- data/tracks/haskell/exercises/binary/test/Tests.hs +0 -1
- data/tracks/haskell/exercises/binary-search-tree/package.yaml +1 -0
- data/tracks/haskell/exercises/binary-search-tree/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/bob/package.yaml +1 -0
- data/tracks/haskell/exercises/bob/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/bowling/package.yaml +1 -0
- data/tracks/haskell/exercises/bowling/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/bracket-push/package.yaml +1 -0
- data/tracks/haskell/exercises/bracket-push/test/Tests.hs +1 -6
- data/tracks/haskell/exercises/change/package.yaml +1 -0
- data/tracks/haskell/exercises/change/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/clock/package.yaml +1 -0
- data/tracks/haskell/exercises/clock/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/connect/package.yaml +1 -0
- data/tracks/haskell/exercises/connect/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/crypto-square/package.yaml +1 -0
- data/tracks/haskell/exercises/crypto-square/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/custom-set/package.yaml +1 -0
- data/tracks/haskell/exercises/custom-set/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/difference-of-squares/package.yaml +1 -0
- data/tracks/haskell/exercises/difference-of-squares/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/dominoes/package.yaml +1 -0
- data/tracks/haskell/exercises/dominoes/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/etl/package.yaml +1 -0
- data/tracks/haskell/exercises/etl/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/food-chain/package.yaml +1 -0
- data/tracks/haskell/exercises/forth/package.yaml +1 -0
- data/tracks/haskell/exercises/forth/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/gigasecond/package.yaml +1 -0
- data/tracks/haskell/exercises/gigasecond/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/go-counting/package.yaml +1 -0
- data/tracks/haskell/exercises/go-counting/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/grade-school/package.yaml +1 -0
- data/tracks/haskell/exercises/grade-school/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/grains/package.yaml +1 -0
- data/tracks/haskell/exercises/grains/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/hamming/package.yaml +1 -0
- data/tracks/haskell/exercises/hamming/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/hello-world/package.yaml +1 -0
- data/tracks/haskell/exercises/hexadecimal/package.yaml +1 -0
- data/tracks/haskell/exercises/hexadecimal/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/house/package.yaml +1 -0
- data/tracks/haskell/exercises/kindergarten-garden/package.yaml +1 -0
- data/tracks/haskell/exercises/kindergarten-garden/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/largest-series-product/package.yaml +1 -0
- data/tracks/haskell/exercises/largest-series-product/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/leap/package.yaml +1 -0
- data/tracks/haskell/exercises/leap/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/lens-person/package.yaml +1 -0
- data/tracks/haskell/exercises/lens-person/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/linked-list/package.yaml +1 -0
- data/tracks/haskell/exercises/linked-list/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/list-ops/package.yaml +1 -0
- data/tracks/haskell/exercises/list-ops/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/luhn/package.yaml +1 -0
- data/tracks/haskell/exercises/luhn/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/matrix/package.yaml +1 -0
- data/tracks/haskell/exercises/matrix/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/meetup/package.yaml +1 -0
- data/tracks/haskell/exercises/meetup/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/minesweeper/package.yaml +1 -0
- data/tracks/haskell/exercises/minesweeper/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/nth-prime/package.yaml +1 -0
- data/tracks/haskell/exercises/nth-prime/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/nucleotide-count/package.yaml +1 -0
- data/tracks/haskell/exercises/nucleotide-count/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/ocr-numbers/package.yaml +1 -0
- data/tracks/haskell/exercises/ocr-numbers/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/octal/package.yaml +1 -0
- data/tracks/haskell/exercises/octal/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/palindrome-products/package.yaml +1 -0
- data/tracks/haskell/exercises/palindrome-products/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/pangram/package.yaml +1 -0
- data/tracks/haskell/exercises/pangram/test/Tests.hs +0 -5
- data/tracks/haskell/exercises/parallel-letter-frequency/package.yaml +1 -0
- data/tracks/haskell/exercises/parallel-letter-frequency/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/pascals-triangle/package.yaml +1 -0
- data/tracks/haskell/exercises/pascals-triangle/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/phone-number/package.yaml +1 -0
- data/tracks/haskell/exercises/phone-number/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/pig-latin/package.yaml +1 -0
- data/tracks/haskell/exercises/pig-latin/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/pov/package.yaml +1 -0
- data/tracks/haskell/exercises/pov/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/prime-factors/package.yaml +1 -0
- data/tracks/haskell/exercises/prime-factors/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/pythagorean-triplet/package.yaml +1 -0
- data/tracks/haskell/exercises/pythagorean-triplet/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/queen-attack/package.yaml +1 -0
- data/tracks/haskell/exercises/queen-attack/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/raindrops/package.yaml +1 -0
- data/tracks/haskell/exercises/raindrops/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/rna-transcription/package.yaml +1 -0
- data/tracks/haskell/exercises/rna-transcription/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/robot-name/package.yaml +1 -0
- data/tracks/haskell/exercises/robot-name/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/robot-simulator/package.yaml +1 -0
- data/tracks/haskell/exercises/robot-simulator/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/roman-numerals/package.yaml +1 -0
- data/tracks/haskell/exercises/roman-numerals/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/run-length-encoding/package.yaml +1 -0
- data/tracks/haskell/exercises/run-length-encoding/test/Tests.hs +0 -4
- data/tracks/haskell/exercises/saddle-points/package.yaml +1 -0
- data/tracks/haskell/exercises/saddle-points/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/say/package.yaml +1 -0
- data/tracks/haskell/exercises/say/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/scrabble-score/package.yaml +1 -0
- data/tracks/haskell/exercises/scrabble-score/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/secret-handshake/package.yaml +1 -0
- data/tracks/haskell/exercises/secret-handshake/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/series/package.yaml +1 -0
- data/tracks/haskell/exercises/series/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/sgf-parsing/package.yaml +1 -0
- data/tracks/haskell/exercises/sgf-parsing/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/sieve/package.yaml +1 -0
- data/tracks/haskell/exercises/sieve/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/simple-cipher/package.yaml +1 -0
- data/tracks/haskell/exercises/simple-cipher/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/simple-linked-list/package.yaml +1 -0
- data/tracks/haskell/exercises/simple-linked-list/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/space-age/package.yaml +1 -0
- data/tracks/haskell/exercises/space-age/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/strain/package.yaml +1 -0
- data/tracks/haskell/exercises/strain/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/sublist/package.yaml +1 -0
- data/tracks/haskell/exercises/sublist/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/sum-of-multiples/package.yaml +1 -0
- data/tracks/haskell/exercises/sum-of-multiples/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/triangle/package.yaml +1 -0
- data/tracks/haskell/exercises/triangle/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/trinary/package.yaml +1 -0
- data/tracks/haskell/exercises/trinary/test/Tests.hs +0 -3
- data/tracks/haskell/exercises/word-count/package.yaml +1 -0
- data/tracks/haskell/exercises/word-count/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/wordy/package.yaml +1 -0
- data/tracks/haskell/exercises/wordy/test/Tests.hs +0 -2
- data/tracks/haskell/exercises/zebra-puzzle/package.yaml +1 -0
- data/tracks/haskell/exercises/zipper/package.yaml +1 -0
- data/tracks/haskell/exercises/zipper/test/Tests.hs +0 -3
- data/tracks/java/exercises/book-store/src/test/java/BookstoreTest.java +12 -12
- data/tracks/java/exercises/ocr-numbers/src/test/java/OpticalCharacterReaderTest.java +16 -16
- data/tracks/java/exercises/strain/src/test/java/StrainTest.java +11 -11
- data/tracks/perl6/README.md +12 -0
- data/tracks/perl6/bin/README.md +3 -0
- data/tracks/perl6/config.json +20 -20
- data/tracks/perl6/exercises/accumulate/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/all-your-base/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/allergies/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/anagram/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/atbash-cipher/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/binary/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/bob/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/bob/bob.t +181 -180
- data/tracks/perl6/exercises/bob/example.yaml +1 -0
- data/tracks/perl6/exercises/grade-school/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/grade-school/grade-school.t +9 -18
- data/tracks/perl6/exercises/grains/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/hello-world/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/hello-world/example.yaml +1 -0
- data/tracks/perl6/exercises/hello-world/hello-world.t +38 -43
- data/tracks/perl6/exercises/leap/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/leap/leap.t +40 -42
- data/tracks/perl6/exercises/phone-number/{Example.pm → Example.pm6} +2 -2
- data/tracks/perl6/exercises/phone-number/PhoneNumber.pm6 +1 -1
- data/tracks/perl6/exercises/phone-number/example.yaml +2 -2
- data/tracks/perl6/exercises/phone-number/phone-number.t +3 -9
- data/tracks/perl6/exercises/raindrops/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/rna-transcription/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/robot-name/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/scrabble-score/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/space-age/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/trinary/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/word-count/{Example.pm → Example.pm6} +0 -0
- data/tracks/perl6/exercises/wordy/{Example.pm → Example.pm6} +0 -0
- data/tracks/python/.github/stale.yml +4 -4
- data/tracks/python/config.json +24 -0
- data/tracks/python/exercises/alphametics/alphametics.py +2 -0
- data/tracks/python/exercises/alphametics/alphametics_test.py +71 -0
- data/tracks/python/exercises/alphametics/example.py +29 -0
- data/tracks/python/exercises/book-store/book_store.py +2 -0
- data/tracks/python/exercises/book-store/book_store_test.py +72 -0
- data/tracks/python/exercises/book-store/example.py +29 -0
- data/tracks/python/exercises/meetup/meetup_test.py +341 -1
- data/tracks/python/exercises/tournament/example.py +45 -0
- data/tracks/python/exercises/tournament/tournament.py +2 -0
- data/tracks/python/exercises/tournament/tournament_test.py +70 -0
- data/tracks/python/exercises/variable-length-quantity/example.py +34 -0
- data/tracks/python/exercises/variable-length-quantity/variable_length_quantity.py +6 -0
- data/tracks/python/exercises/variable-length-quantity/variable_length_quantity_test.py +100 -0
- data/tracks/r/config.json +23 -23
- data/tracks/r/exercises/perfect-numbers/test_perfect-numbers.R +1 -1
- data/tracks/r/exercises/prime-factors/test_prime-factors.R +2 -0
- data/tracks/r/exercises/tournament/example.R +2 -5
- data/tracks/scala/exercises/leap/example.scala +4 -4
- data/tracks/scala/exercises/leap/src/main/scala/Leap.scala +3 -0
- data/tracks/scala/exercises/leap/src/test/scala/LeapTest.scala +6 -6
- metadata +43 -22
@@ -10,6 +10,7 @@ tests: |
|
|
10
10
|
exercise_comment: The name of this exercise.
|
11
11
|
module_comment: "%*ENV<EXERCISM> is for tests not directly for the exercise, don't worry about these :)"
|
12
12
|
version_comment: The version we will be matching against the exercise.
|
13
|
+
lib_comment: Look for the module inside the same directory as this test file.
|
13
14
|
plan_comment: This is how many tests we expect to run.
|
14
15
|
use_test_comment: Check that the module can be use-d.
|
15
16
|
version_test_comment: "If the exercise is updated, we want to make sure other people testing\nyour code don't think you've made a mistake if things have changed!"
|
File without changes
|
@@ -6,10 +6,11 @@ use lib $?FILE.IO.dirname;
|
|
6
6
|
my $exercise = 'GradeSchool';
|
7
7
|
my $version = v1;
|
8
8
|
my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
|
9
|
-
plan
|
9
|
+
plan 10;
|
10
10
|
|
11
11
|
use-ok $module or bail-out;
|
12
12
|
require ::($module);
|
13
|
+
|
13
14
|
if ::($exercise).^ver !~~ $version {
|
14
15
|
warn "\nExercise version mismatch. Further tests may fail!"
|
15
16
|
~ "\n$exercise is $(::($exercise).^ver.gist). "
|
@@ -17,35 +18,25 @@ if ::($exercise).^ver !~~ $version {
|
|
17
18
|
bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
|
18
19
|
}
|
19
20
|
|
20
|
-
|
21
|
-
BEGIN { @classes = <Roster> };
|
22
|
-
subtest 'Class(es)', {
|
23
|
-
plan 1;
|
24
|
-
eval-lives-ok "use $module; ::('$_').new or die 'Could not use .new method on class $_.\'", $_ for @classes;
|
25
|
-
} or bail-out 'All classes must be defined and exported.';
|
26
|
-
require ::($module) @classes.eager;
|
21
|
+
require ::($module) <Roster>;
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
ok ::($class).can($_), $_ for <add-student list-grade list-all>;
|
32
|
-
}
|
23
|
+
subtest "Roster class methods", {
|
24
|
+
plan 3;
|
25
|
+
ok ::('Roster').can($_), $_ for <add-student list-grade list-all>;
|
33
26
|
}
|
34
|
-
|
35
|
-
my $roster = Roster.new;
|
36
|
-
|
27
|
+
my $roster = ::('Roster').new;
|
37
28
|
ok $roster.?add-student(:name('Jim'), :2grade), 'Add Jim to grade 2';
|
38
29
|
is $roster.?list-grade(2), <Jim>, 'List grade 2';
|
39
30
|
ok $roster.?add-student(:name('Zoe'), :2grade), 'Add Zoe to grade 2';
|
40
31
|
ok $roster.?add-student(:name('Barb'), :1grade), 'Add Barb to grade 1';
|
41
32
|
is $roster.?list-grade(2), <Jim Zoe>, 'List grade 2';
|
42
33
|
is $roster.?list-grade(1), <Barb>, 'List grade 1';
|
43
|
-
|
44
34
|
subtest 'Additional students', {
|
45
35
|
plan 6;
|
46
36
|
ok $roster.?add-student(:name($_), :1grade), "Add $_ to grade 1" for <Charlie Anna>;
|
47
37
|
ok $roster.?add-student(:name('Alex'), :2grade), 'Add Alex to grade 2';
|
48
38
|
ok $roster.?add-student(:name($_), :3grade), "Add $_ to grade 3" for <Tom Dick Harry>;
|
49
39
|
}
|
50
|
-
|
51
40
|
is $roster.?list-all, ('Grade 1', <Anna Barb Charlie>, 'Grade 2', <Alex Jim Zoe>, 'Grade 3', <Dick Harry Tom>), 'List all';
|
41
|
+
|
42
|
+
done-testing;
|
File without changes
|
File without changes
|
@@ -10,6 +10,7 @@ tests: |
|
|
10
10
|
exercise_comment: The name of this exercise.
|
11
11
|
module_comment: "%*ENV<EXERCISM> is for tests not directly for the exercise, don't worry about these :)"
|
12
12
|
version_comment: The version we will be matching against the exercise.
|
13
|
+
lib_comment: Look for the module inside the same directory as this test file.
|
13
14
|
plan_comment: This is how many tests we expect to run.
|
14
15
|
use_test_comment: Check that the module can be use-d.
|
15
16
|
version_test_comment: "If the exercise is updated, we want to make sure other people testing\nyour code don't think you've made a mistake if things have changed!"
|
@@ -1,20 +1,20 @@
|
|
1
1
|
#!/usr/bin/env perl6
|
2
2
|
use v6;
|
3
3
|
use Test;
|
4
|
-
use lib my $dir = $?FILE.IO.dirname;
|
4
|
+
use lib my $dir = $?FILE.IO.dirname; #`[Look for the module inside the same directory as this test file.]
|
5
5
|
use JSON::Tiny;
|
6
6
|
|
7
|
-
my $exercise = 'HelloWorld';
|
8
|
-
my $version = v2;
|
9
|
-
my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
|
10
|
-
plan
|
7
|
+
my $exercise = 'HelloWorld'; #`[The name of this exercise.]
|
8
|
+
my $version = v2; #`[The version we will be matching against the exercise.]
|
9
|
+
my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise; #`[%*ENV<EXERCISM> is for tests not directly for the exercise, don't worry about these :)]
|
10
|
+
plan 3; #`[This is how many tests we expect to run.]
|
11
11
|
|
12
|
-
|
12
|
+
#`[Check that the module can be use-d.]
|
13
13
|
use-ok $module or bail-out;
|
14
14
|
require ::($module);
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
#`[If the exercise is updated, we want to make sure other people testing
|
17
|
+
your code don't think you've made a mistake if things have changed!]
|
18
18
|
if ::($exercise).^ver !~~ $version {
|
19
19
|
warn "\nExercise version mismatch. Further tests may fail!"
|
20
20
|
~ "\n$exercise is $(::($exercise).^ver.gist). "
|
@@ -22,42 +22,37 @@ if ::($exercise).^ver !~~ $version {
|
|
22
22
|
bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
|
23
23
|
}
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
} else { skip }
|
43
|
-
|
44
|
-
# There are no more tests after this :)
|
45
|
-
done-testing;
|
46
|
-
|
47
|
-
# 'INIT' is a phaser, it makes sure that the test data is available before everything else
|
48
|
-
# starts running (otherwise we'd have to shove the test data into the middle of the file!)
|
25
|
+
#`[Import '&hello' from 'HelloWorld']
|
26
|
+
require ::($module) <&hello>;
|
27
|
+
|
28
|
+
my $c-data;
|
29
|
+
#`[Go through the cases (hiding at the bottom of this file)
|
30
|
+
and check that &hello gives us the correct response.]
|
31
|
+
is &::('hello')(), |.<expected description> for @($c-data<cases>);
|
32
|
+
|
33
|
+
#`[Ignore this for your exercise! Tells Exercism folks when exercise cases become out of date.]
|
34
|
+
if %*ENV<EXERCISM> && (my $c-data-file =
|
35
|
+
"$dir/../../x-common/exercises/{$dir.IO.resolve.basename}/canonical-data.json".IO.resolve) ~~ :f
|
36
|
+
{ is-deeply $c-data, from-json($c-data-file.slurp), 'canonical-data' } else { skip }
|
37
|
+
|
38
|
+
done-testing; #`[There are no more tests after this :)]
|
39
|
+
|
40
|
+
#`['INIT' is a phaser, it makes sure that the test data is available before everything else
|
41
|
+
starts running (otherwise we'd have to shove the test data into the middle of the file!)]
|
49
42
|
INIT {
|
50
|
-
|
43
|
+
$c-data := from-json q:to/END/;
|
44
|
+
|
45
|
+
{
|
46
|
+
"exercise": "hello-world",
|
47
|
+
"version": "1.0.0",
|
48
|
+
"cases": [
|
51
49
|
{
|
52
|
-
"
|
53
|
-
"
|
54
|
-
"
|
55
|
-
{
|
56
|
-
"description": "Say Hi!",
|
57
|
-
"property": "hello",
|
58
|
-
"expected": "Hello, World!"
|
59
|
-
}
|
60
|
-
]
|
50
|
+
"description": "Say Hi!",
|
51
|
+
"property": "hello",
|
52
|
+
"expected": "Hello, World!"
|
61
53
|
}
|
62
|
-
|
54
|
+
]
|
55
|
+
}
|
56
|
+
|
57
|
+
END
|
63
58
|
}
|
File without changes
|
@@ -7,10 +7,11 @@ use JSON::Tiny;
|
|
7
7
|
my $exercise = 'Leap';
|
8
8
|
my $version = v1;
|
9
9
|
my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
|
10
|
-
plan
|
10
|
+
plan 6;
|
11
11
|
|
12
12
|
use-ok $module or bail-out;
|
13
13
|
require ::($module);
|
14
|
+
|
14
15
|
if ::($exercise).^ver !~~ $version {
|
15
16
|
warn "\nExercise version mismatch. Further tests may fail!"
|
16
17
|
~ "\n$exercise is $(::($exercise).^ver.gist). "
|
@@ -18,53 +19,50 @@ if ::($exercise).^ver !~~ $version {
|
|
18
19
|
bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
|
19
20
|
}
|
20
21
|
|
21
|
-
|
22
|
-
BEGIN { @subs = <&is-leap-year> };
|
23
|
-
subtest 'Subroutine(s)', {
|
24
|
-
plan 1;
|
25
|
-
eval-lives-ok "use $module; ::('$_').defined or die '$_ is not defined.'", $_ for @subs;
|
26
|
-
} or bail-out 'All subroutines must be defined and exported.';
|
27
|
-
require ::($module) @subs.eager;
|
22
|
+
require ::($module) <&is-leap-year>;
|
28
23
|
|
29
|
-
|
24
|
+
my $c-data;
|
25
|
+
is &::('is-leap-year')(.<input>), |.<expected description> for @($c-data<cases>);
|
30
26
|
|
31
|
-
if %*ENV<EXERCISM> && (my $c-data-file =
|
32
|
-
|
33
|
-
} else { skip }
|
27
|
+
if %*ENV<EXERCISM> && (my $c-data-file =
|
28
|
+
"$dir/../../x-common/exercises/{$dir.IO.resolve.basename}/canonical-data.json".IO.resolve) ~~ :f
|
29
|
+
{ is-deeply $c-data, from-json($c-data-file.slurp), 'canonical-data' } else { skip }
|
34
30
|
|
35
31
|
done-testing;
|
36
32
|
|
37
33
|
INIT {
|
38
|
-
|
34
|
+
$c-data := from-json q:to/END/;
|
35
|
+
|
36
|
+
{
|
37
|
+
"exercise": "leap",
|
38
|
+
"version": "1.0.0",
|
39
|
+
"cases": [
|
40
|
+
{
|
41
|
+
"description": "year not divisible by 4: common year",
|
42
|
+
"property": "leapYear",
|
43
|
+
"input": 2015,
|
44
|
+
"expected": false
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"description": "year divisible by 4, not divisible by 100: leap year",
|
48
|
+
"property": "leapYear",
|
49
|
+
"input": 2016,
|
50
|
+
"expected": true
|
51
|
+
},
|
39
52
|
{
|
40
|
-
"
|
41
|
-
"
|
42
|
-
"
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
"description": "year divisible by 4, not divisible by 100: leap year",
|
51
|
-
"property": "leapYear",
|
52
|
-
"input": 2016,
|
53
|
-
"expected": true
|
54
|
-
},
|
55
|
-
{
|
56
|
-
"description": "year divisible by 100, not divisible by 400: common year",
|
57
|
-
"property": "leapYear",
|
58
|
-
"input": 2100,
|
59
|
-
"expected": false
|
60
|
-
},
|
61
|
-
{
|
62
|
-
"description": "year divisible by 400: leap year",
|
63
|
-
"property": "leapYear",
|
64
|
-
"input": 2000,
|
65
|
-
"expected": true
|
66
|
-
}
|
67
|
-
]
|
53
|
+
"description": "year divisible by 100, not divisible by 400: common year",
|
54
|
+
"property": "leapYear",
|
55
|
+
"input": 2100,
|
56
|
+
"expected": false
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"description": "year divisible by 400: leap year",
|
60
|
+
"property": "leapYear",
|
61
|
+
"input": 2000,
|
62
|
+
"expected": true
|
68
63
|
}
|
69
|
-
|
64
|
+
]
|
65
|
+
}
|
66
|
+
|
67
|
+
END
|
70
68
|
}
|
@@ -1,6 +1,6 @@
|
|
1
|
-
unit module Phone:ver<
|
1
|
+
unit module Phone:ver<3>;
|
2
2
|
|
3
3
|
sub clean-number ($number is copy) is export {
|
4
|
-
$number ~~
|
4
|
+
$number ~~ s:g/<:!Nd>//;
|
5
5
|
$number ~~ /^ 1? ( [ <[2..9]> <:Nd> ** 2 ] ** 2 <:Nd> ** 4 ) $/ ?? ~$0 !! Nil;
|
6
6
|
}
|
@@ -5,9 +5,9 @@ use lib my $dir = $?FILE.IO.dirname;
|
|
5
5
|
use JSON::Tiny;
|
6
6
|
|
7
7
|
my $exercise = 'Phone';
|
8
|
-
my $version =
|
8
|
+
my $version = v3;
|
9
9
|
my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
|
10
|
-
plan
|
10
|
+
plan 14;
|
11
11
|
|
12
12
|
use-ok $module or bail-out;
|
13
13
|
require ::($module);
|
@@ -41,7 +41,7 @@ $c-data := from-json q:to/END/;
|
|
41
41
|
|
42
42
|
{
|
43
43
|
"exercise": "phone-number",
|
44
|
-
"version": "1.
|
44
|
+
"version": "1.2.0",
|
45
45
|
"cases": [
|
46
46
|
{
|
47
47
|
"description": "Cleanup user-entered phone numbers",
|
@@ -111,12 +111,6 @@ $c-data := from-json q:to/END/;
|
|
111
111
|
"phrase": "123-@:!-7890",
|
112
112
|
"expected": null
|
113
113
|
},
|
114
|
-
{
|
115
|
-
"description": "invalid with right number of digits but letters mixed in",
|
116
|
-
"property": "clean",
|
117
|
-
"phrase": "1a2b3c4d5e6f7g8h9i0j",
|
118
|
-
"expected": null
|
119
|
-
},
|
120
114
|
{
|
121
115
|
"description": "invalid if area code does not start with 2-9",
|
122
116
|
"property": "clean",
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,17 +1,17 @@
|
|
1
1
|
# Number of days of inactivity before an issue becomes stale
|
2
|
-
daysUntilStale:
|
2
|
+
daysUntilStale: 60
|
3
3
|
# Number of days of inactivity before a stale issue is closed
|
4
4
|
daysUntilClose: 7
|
5
5
|
# Issues with these labels will never be considered stale
|
6
6
|
exemptLabels:
|
7
|
+
- discussion
|
7
8
|
- pinned
|
8
|
-
- security
|
9
9
|
# Label to use when marking an issue as stale
|
10
10
|
staleLabel: on hiatus
|
11
11
|
# Comment to post when marking an issue as stale. Set to `false` to disable
|
12
12
|
markComment: >
|
13
|
-
This issue has been automatically marked as `on hiatus because it has not had
|
13
|
+
This issue has been automatically marked as `on hiatus` because it has not had
|
14
14
|
recent activity. It will be closed if no further activity occurs. Thank you
|
15
15
|
for your contributions.
|
16
16
|
# Comment to post when closing a stale issue. Set to `false` to disable
|
17
|
-
closeComment: false
|
17
|
+
closeComment: false
|
data/tracks/python/config.json
CHANGED
@@ -416,6 +416,12 @@
|
|
416
416
|
"topics": [
|
417
417
|
]
|
418
418
|
},
|
419
|
+
{
|
420
|
+
"slug": "book-store",
|
421
|
+
"difficulty": 1,
|
422
|
+
"topics": [
|
423
|
+
]
|
424
|
+
},
|
419
425
|
{
|
420
426
|
"slug": "linked-list",
|
421
427
|
"difficulty": 1,
|
@@ -428,6 +434,12 @@
|
|
428
434
|
"topics": [
|
429
435
|
]
|
430
436
|
},
|
437
|
+
{
|
438
|
+
"slug": "variable-length-quantity",
|
439
|
+
"difficulty": 1,
|
440
|
+
"topics": [
|
441
|
+
]
|
442
|
+
},
|
431
443
|
{
|
432
444
|
"slug": "all-your-base",
|
433
445
|
"difficulty": 4,
|
@@ -463,6 +475,18 @@
|
|
463
475
|
"strings",
|
464
476
|
"searching"
|
465
477
|
]
|
478
|
+
},
|
479
|
+
{
|
480
|
+
"slug": "alphametics",
|
481
|
+
"difficulty": 6,
|
482
|
+
"topics": [
|
483
|
+
]
|
484
|
+
},
|
485
|
+
{
|
486
|
+
"slug": "tournament",
|
487
|
+
"difficulty": 1,
|
488
|
+
"topics": [
|
489
|
+
]
|
466
490
|
}
|
467
491
|
],
|
468
492
|
"deprecated": [
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import unittest
|
2
|
+
|
3
|
+
from alphametics import solve
|
4
|
+
|
5
|
+
|
6
|
+
# test cases adapted from `x-common//canonical-data.json` @ version: 1.0.0
|
7
|
+
|
8
|
+
class TestAlphametics(unittest.TestCase):
|
9
|
+
def test_puzzle_with_three_letters(self):
|
10
|
+
self.assertEqual(solve("I + BB == ILL"), {"I": 1, "B": 9, "L": 0})
|
11
|
+
|
12
|
+
def solution_must_have_unique_value_for_each_letter(self):
|
13
|
+
self.assertEqual(solve("A == B"), {})
|
14
|
+
|
15
|
+
def leading_zero_solution_is_invalid(self):
|
16
|
+
self.assertEqual(solve("ACA + DD == BD"), {})
|
17
|
+
|
18
|
+
def test_puzzle_with_four_letters(self):
|
19
|
+
self.assertEqual(
|
20
|
+
solve("AS + A == MOM"), {"A": 9, "S": 2, "M": 1, "O": 0})
|
21
|
+
|
22
|
+
def puzzle_with_six_letters(self):
|
23
|
+
self.assertEqual(
|
24
|
+
solve("NO + NO + TOO == LATE"),
|
25
|
+
{"N": 7,
|
26
|
+
"O": 4,
|
27
|
+
"T": 9,
|
28
|
+
"L": 1,
|
29
|
+
"A": 0,
|
30
|
+
"E": 2})
|
31
|
+
|
32
|
+
def test_puzzle_with_seven_letters(self):
|
33
|
+
self.assertEqual(
|
34
|
+
solve("HE + SEES + THE == LIGHT"),
|
35
|
+
{"E": 4,
|
36
|
+
"G": 2,
|
37
|
+
"H": 5,
|
38
|
+
"I": 0,
|
39
|
+
"L": 1,
|
40
|
+
"S": 9,
|
41
|
+
"T": 7})
|
42
|
+
|
43
|
+
def test_puzzle_with_eight_letters(self):
|
44
|
+
self.assertEqual(
|
45
|
+
solve("SEND + MORE == MONEY"),
|
46
|
+
{"S": 9,
|
47
|
+
"E": 5,
|
48
|
+
"N": 6,
|
49
|
+
"D": 7,
|
50
|
+
"M": 1,
|
51
|
+
"O": 0,
|
52
|
+
"R": 8,
|
53
|
+
"Y": 2})
|
54
|
+
|
55
|
+
def test_puzzle_with_ten_letters(self):
|
56
|
+
self.assertEqual(
|
57
|
+
solve("AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE"),
|
58
|
+
{"A": 5,
|
59
|
+
"D": 3,
|
60
|
+
"E": 4,
|
61
|
+
"F": 7,
|
62
|
+
"G": 8,
|
63
|
+
"N": 0,
|
64
|
+
"O": 2,
|
65
|
+
"R": 1,
|
66
|
+
"S": 6,
|
67
|
+
"T": 9})
|
68
|
+
|
69
|
+
|
70
|
+
if __name__ == '__main__':
|
71
|
+
unittest.main()
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from itertools import combinations, permutations
|
2
|
+
|
3
|
+
|
4
|
+
def check_leading_zeros(*numbers):
|
5
|
+
return any(n[0] == '0' for n in numbers)
|
6
|
+
|
7
|
+
|
8
|
+
def test_equation(puzzle, substitutions):
|
9
|
+
equation = ''.join(substitutions.get(char) or char for char in puzzle)
|
10
|
+
left, right = equation.split(' == ')
|
11
|
+
left_numbers = left.split(' + ')
|
12
|
+
|
13
|
+
if check_leading_zeros(right, *left_numbers):
|
14
|
+
return False
|
15
|
+
|
16
|
+
return sum(map(int, left_numbers)) == int(right)
|
17
|
+
|
18
|
+
|
19
|
+
def solve(puzzle):
|
20
|
+
letters = set(char for char in puzzle if char.isupper())
|
21
|
+
numbers = map(str, range(10))
|
22
|
+
|
23
|
+
for c in combinations(numbers, len(letters)):
|
24
|
+
for p in permutations(c):
|
25
|
+
substitutions = dict(zip(letters, p))
|
26
|
+
if test_equation(puzzle, substitutions):
|
27
|
+
return {k: int(v) for k, v in substitutions.items()}
|
28
|
+
|
29
|
+
return {} # no solution found
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import unittest
|
2
|
+
|
3
|
+
from book_store import calculate_total
|
4
|
+
|
5
|
+
|
6
|
+
# test cases adapted from `x-common//canonical-data.json` @ version: 1.0.0
|
7
|
+
|
8
|
+
class BookStoreTests(unittest.TestCase):
|
9
|
+
def test_only_a_single_book(self):
|
10
|
+
self.assertAlmostEqual(calculate_total([1]), 8.00,
|
11
|
+
places=2)
|
12
|
+
|
13
|
+
def test_two_of_the_same_book(self):
|
14
|
+
self.assertAlmostEqual(calculate_total([2, 2]), 16.00,
|
15
|
+
places=2)
|
16
|
+
|
17
|
+
def test_empty_basket(self):
|
18
|
+
self.assertAlmostEqual(calculate_total([]), 0.00,
|
19
|
+
places=2)
|
20
|
+
|
21
|
+
def test_two_different_books(self):
|
22
|
+
self.assertAlmostEqual(calculate_total([1, 2]), 15.20,
|
23
|
+
places=2)
|
24
|
+
|
25
|
+
def test_three_different_books(self):
|
26
|
+
self.assertAlmostEqual(calculate_total([1, 2, 3]), 21.60,
|
27
|
+
places=2)
|
28
|
+
|
29
|
+
def test_four_different_books(self):
|
30
|
+
self.assertAlmostEqual(calculate_total([1, 2, 3, 4]), 25.60,
|
31
|
+
places=2)
|
32
|
+
|
33
|
+
def test_five_different_books(self):
|
34
|
+
self.assertAlmostEqual(
|
35
|
+
calculate_total([1, 2, 3, 4, 5]), 30.00,
|
36
|
+
places=2)
|
37
|
+
|
38
|
+
def test_two_groups_of_4_is_cheaper_than_group_of_5_plus_group_of_3(self):
|
39
|
+
self.assertAlmostEqual(
|
40
|
+
calculate_total([1, 1, 2, 2, 3, 3, 4, 5]), 51.20,
|
41
|
+
places=2)
|
42
|
+
|
43
|
+
def test_group_of_4_plus_group_of_2_is_cheaper_than_2_groups_of_3(self):
|
44
|
+
self.assertAlmostEqual(
|
45
|
+
calculate_total([1, 1, 2, 2, 3, 4]), 40.80,
|
46
|
+
places=2)
|
47
|
+
|
48
|
+
def test_two_each_of_first_4_books_and_1_copy_each_of_rest(self):
|
49
|
+
self.assertAlmostEqual(
|
50
|
+
calculate_total([1, 1, 2, 2, 3, 3, 4, 4, 5]), 55.60,
|
51
|
+
places=2)
|
52
|
+
|
53
|
+
def test_two_copies_of_each_book(self):
|
54
|
+
self.assertAlmostEqual(
|
55
|
+
calculate_total([1, 1, 2, 2, 3, 3, 4, 4, 5, 5]), 60.00,
|
56
|
+
places=2)
|
57
|
+
|
58
|
+
def test_three_copies_of_first_book_and_2_each_of_remaining(self):
|
59
|
+
self.assertAlmostEqual(
|
60
|
+
calculate_total([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1]),
|
61
|
+
68.00,
|
62
|
+
places=2)
|
63
|
+
|
64
|
+
def test_three_each_of_first_2_books_and_2_each_of_remaining_books(self):
|
65
|
+
self.assertAlmostEqual(
|
66
|
+
calculate_total([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2]),
|
67
|
+
75.20,
|
68
|
+
places=2)
|
69
|
+
|
70
|
+
|
71
|
+
if __name__ == '__main__':
|
72
|
+
unittest.main()
|
@@ -0,0 +1,29 @@
|
|
1
|
+
BOOK_PRICE = 8
|
2
|
+
|
3
|
+
|
4
|
+
def _group_price(size):
|
5
|
+
discounts = [0, .05, .1, .2, .25]
|
6
|
+
if not (0 < size <= 5):
|
7
|
+
raise ValueError('size must be in 1..' + len(discounts))
|
8
|
+
return 8 * size * (1 - discounts[size - 1])
|
9
|
+
|
10
|
+
|
11
|
+
def calculate_total(books, price_so_far=0.):
|
12
|
+
if not books:
|
13
|
+
return price_so_far
|
14
|
+
|
15
|
+
groups = list(set(books))
|
16
|
+
min_price = float('inf')
|
17
|
+
|
18
|
+
for i in range(len(groups)):
|
19
|
+
|
20
|
+
remaining_books = books[:]
|
21
|
+
|
22
|
+
for v in groups[:i + 1]:
|
23
|
+
remaining_books.remove(v)
|
24
|
+
|
25
|
+
price = calculate_total(remaining_books,
|
26
|
+
price_so_far + _group_price(i + 1))
|
27
|
+
min_price = min(min_price, price)
|
28
|
+
|
29
|
+
return min_price
|