trackler 2.1.0.19 → 2.1.0.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/verify-metadata +1 -1
- data/lib/trackler/implementation.rb +1 -9
- data/lib/trackler/version.rb +1 -1
- data/tracks/go/exercises/tree-building/tree_test.go +1 -1
- data/tracks/haskell/.travis.yml +1 -0
- data/tracks/haskell/bin/test-example +17 -5
- data/tracks/haskell/bin/test-stub +14 -3
- data/tracks/java/exercises/build.gradle +3 -3
- data/tracks/java/exercises/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java +1 -1
- data/tracks/javascript/config.json +21 -1
- data/tracks/javascript/exercises/alphametics/alphametics.spec.js +95 -0
- data/tracks/javascript/exercises/alphametics/example.js +107 -0
- data/tracks/perl6/bin/README.md +5 -3
- data/tracks/perl6/docs/LEARNING.md +7 -0
- data/tracks/r/exercises/anagram/test_anagram.R +33 -52
- data/tracks/r/exercises/bob/test_bob.R +52 -73
- data/tracks/r/exercises/difference-of-squares/test_difference-of-squares.R +1 -2
- data/tracks/r/exercises/grains/test_grains.R +1 -1
- data/tracks/r/exercises/hamming/test_hamming.R +1 -1
- data/tracks/r/exercises/hello-world/test_hello-world.R +1 -1
- data/tracks/r/exercises/isogram/test_isogram.R +1 -1
- data/tracks/r/exercises/largest-series-product/test_largest-series-product.R +8 -8
- data/tracks/r/exercises/leap/test_leap.R +1 -1
- data/tracks/r/exercises/luhn/test_luhn.R +1 -1
- data/tracks/r/exercises/pascals-triangle/test_pascals-triangle.R +1 -1
- data/tracks/r/exercises/perfect-numbers/test_perfect-numbers.R +1 -1
- data/tracks/r/exercises/phone-number/test_phone-number.R +1 -1
- data/tracks/r/exercises/prime-factors/test_prime-factors.R +16 -21
- data/tracks/r/exercises/raindrops/test_raindrops.R +1 -1
- data/tracks/r/exercises/rna-transcription/test_rna-transcription.R +1 -1
- data/tracks/r/exercises/rotational-cipher/test_rotational-cipher.R +1 -1
- data/tracks/r/exercises/scrabble-score/test_scrabble-score.R +1 -1
- data/tracks/r/exercises/secret-handshake/test_secret-handshake.R +1 -1
- data/tracks/r/exercises/sieve/test_sieve.R +18 -17
- data/tracks/r/exercises/space-age/test_space-age.R +2 -2
- data/tracks/r/exercises/sum-of-multiples/test_sum-of-multiples.R +11 -11
- data/tracks/r/exercises/tournament/test_tournament.R +142 -107
- data/tracks/r/exercises/word-count/test_word-count.R +38 -17
- data/tracks/vimscript/config.json +23 -0
- data/tracks/vimscript/exercises/anagram/anagram.vader +95 -0
- data/tracks/vimscript/exercises/anagram/anagram.vim +19 -0
- data/tracks/vimscript/exercises/anagram/example.vim +18 -0
- data/tracks/vimscript/exercises/difference-of-squares/difference_of_squares.vader +35 -0
- data/tracks/vimscript/exercises/difference-of-squares/difference_of_squares.vim +24 -0
- data/tracks/vimscript/exercises/difference-of-squares/example.vim +19 -0
- data/tracks/vimscript/exercises/raindrops/example.vim +9 -0
- data/tracks/vimscript/exercises/raindrops/raindrops.vader +53 -0
- data/tracks/vimscript/exercises/raindrops/raindrops.vim +18 -0
- data/tracks/vimscript/exercises/rna-transcription/example.vim +3 -0
- data/tracks/vimscript/exercises/rna-transcription/rna_transcription.vader +23 -0
- data/tracks/vimscript/exercises/rna-transcription/rna_transcription.vim +20 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f87268f3d1befaae03d6be8ac007d0728f59a122
|
4
|
+
data.tar.gz: 54c2c7df1d551ac6082730d8daa399d82fc18886
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f32ea0316601002cd7b6e36d6d67b2ebacc550f8e975761b436a33b5679e26f76da9aa8be03bbce38b58c2574dfd5c67b8f43a07da8ec97954a89e0eb0dee28
|
7
|
+
data.tar.gz: afa5fb4fda304732356033a7fc863a5417427e3f8ab0a2512922572a31418a7cd17c2bb67da348ae89c41a434949e7c6f7f9553138802e4a53c90b95c69197fb
|
data/bin/verify-metadata
CHANGED
@@ -6,7 +6,7 @@ require_relative '../lib/trackler'
|
|
6
6
|
|
7
7
|
missing_problems = []
|
8
8
|
Trackler.tracks.reject do |track|
|
9
|
-
missing_problems += track.
|
9
|
+
missing_problems += track.implementations.reject(&:exists?)
|
10
10
|
end
|
11
11
|
|
12
12
|
missing_problems = missing_problems.uniq
|
@@ -13,6 +13,7 @@ module Trackler
|
|
13
13
|
|
14
14
|
extend Forwardable
|
15
15
|
def_delegators :@problem, :name, :blurb, :description, :source_markdown, :slug, :source, :metadata, :root, :active?, :deprecated?, :source_url, :description_url, :canonical_data_url, :metadata_url
|
16
|
+
def_delegators :@track, :language
|
16
17
|
|
17
18
|
def initialize(track, problem)
|
18
19
|
@track = track
|
@@ -39,15 +40,6 @@ module Trackler
|
|
39
40
|
}].merge("README.md" => readme)
|
40
41
|
end
|
41
42
|
|
42
|
-
def files=(value)
|
43
|
-
warn "DEPRECATION WARNING: 'Implementation#files=' is no longer public, please use 'implementation.merge_files' instead."
|
44
|
-
@files = value
|
45
|
-
end
|
46
|
-
|
47
|
-
def merge_files(new_files)
|
48
|
-
files.merge!(new_files)
|
49
|
-
end
|
50
|
-
|
51
43
|
def zip
|
52
44
|
@zip ||= file_bundle.zip do |io|
|
53
45
|
io.put_next_entry('README.md')
|
data/lib/trackler/version.rb
CHANGED
@@ -226,7 +226,7 @@ func TestMakeTreeSuccess(t *testing.T) {
|
|
226
226
|
}
|
227
227
|
if !reflect.DeepEqual(actual, tt.expected) {
|
228
228
|
t.Fatalf("Build for test case %q returned %s but was expected to return %s.",
|
229
|
-
tt.name, tt.expected
|
229
|
+
tt.name, actual, tt.expected)
|
230
230
|
}
|
231
231
|
}
|
232
232
|
}
|
data/tracks/haskell/.travis.yml
CHANGED
@@ -22,7 +22,15 @@ cleanup() {
|
|
22
22
|
}
|
23
23
|
trap cleanup EXIT INT TERM
|
24
24
|
|
25
|
-
cp -R -L
|
25
|
+
cp -R -L \
|
26
|
+
${exercisedir}/stack.yaml \
|
27
|
+
${exercisedir}/test \
|
28
|
+
${exampledir}/* \
|
29
|
+
"${buildfolder}"
|
30
|
+
|
31
|
+
if [ -d ${exercisedir}/bench ]; then
|
32
|
+
cp -R -L ${exercisedir}/bench "${buildfolder}"
|
33
|
+
fi
|
26
34
|
|
27
35
|
cd $buildfolder
|
28
36
|
|
@@ -39,10 +47,12 @@ exampletype=$(echo "$examplename" | cut -d- -f1)
|
|
39
47
|
|
40
48
|
runstack () {
|
41
49
|
# SET_RESOLVER passed by .travis.yml - sets --resolver if not current.
|
42
|
-
stack "$@" ${SET_RESOLVER}
|
43
|
-
--install-ghc
|
44
|
-
--no-terminal
|
45
|
-
--
|
50
|
+
stack "$@" ${SET_RESOLVER} `# Select the correct resolver. `\
|
51
|
+
--install-ghc `# Download GHC if not in cache.`\
|
52
|
+
--no-terminal `# Terminal detection is broken.`\
|
53
|
+
--bench `# Build benchmarks, but `\
|
54
|
+
--no-run-benchmarks `# do not run them. `\
|
55
|
+
--pedantic `# Enable -Wall and -Werror. `
|
46
56
|
}
|
47
57
|
|
48
58
|
if [ "$exampletype" = "success" ]; then
|
@@ -66,6 +76,8 @@ elif [ "$exampletype" = "error" ]; then
|
|
66
76
|
if runstack "test" "--no-run-tests"; then
|
67
77
|
echo "${exampledir} build succeeded unexpectedly"
|
68
78
|
exit 1
|
79
|
+
else
|
80
|
+
rm -rf "${examplecache}"
|
69
81
|
fi
|
70
82
|
else
|
71
83
|
echo "unknown example type: ${exampledir}"
|
@@ -20,7 +20,16 @@ cleanup() {
|
|
20
20
|
}
|
21
21
|
trap cleanup EXIT INT TERM
|
22
22
|
|
23
|
-
cp -R -L
|
23
|
+
cp -R -L \
|
24
|
+
${exercisedir}/stack.yaml \
|
25
|
+
${exercisedir}/package.yaml \
|
26
|
+
${exercisedir}/src \
|
27
|
+
${exercisedir}/test \
|
28
|
+
"${buildfolder}"
|
29
|
+
|
30
|
+
if [ -d ${exercisedir}/bench ]; then
|
31
|
+
cp -R -L ${exercisedir}/bench "${buildfolder}"
|
32
|
+
fi
|
24
33
|
|
25
34
|
cd $buildfolder
|
26
35
|
|
@@ -38,6 +47,8 @@ if [ -f "${exercisedir}/.meta/DONT-TEST-STUB" ]; then
|
|
38
47
|
echo "only building stub"
|
39
48
|
stack build ${SET_RESOLVER} --install-ghc --no-terminal
|
40
49
|
else
|
41
|
-
echo "
|
42
|
-
stack
|
50
|
+
echo "building stub with everything else"
|
51
|
+
stack build ${SET_RESOLVER} --install-ghc --no-terminal \
|
52
|
+
--test --no-run-tests \
|
53
|
+
--bench --no-run-benchmarks
|
43
54
|
fi
|
@@ -9,14 +9,14 @@ subprojects { project ->
|
|
9
9
|
java.srcDirs = ["src/example/java"]
|
10
10
|
}
|
11
11
|
project["compileJava"].doFirst { compileTask ->
|
12
|
-
println " (source =
|
12
|
+
println " (source = ${compileTask.source.asPath})"
|
13
13
|
}
|
14
14
|
|
15
15
|
starterSource {
|
16
16
|
java.srcDirs = ["src/main/java"]
|
17
17
|
}
|
18
18
|
project["compileStarterSourceJava"].doFirst { compileTask ->
|
19
|
-
println " (source =
|
19
|
+
println " (source = ${compileTask.source.asPath})"
|
20
20
|
}
|
21
21
|
|
22
22
|
// In lieu of being able to disable @Ignore in JUnit tests, we filter
|
@@ -25,7 +25,7 @@ subprojects { project ->
|
|
25
25
|
java.srcDirs = ["build/gen/test/java"]
|
26
26
|
}
|
27
27
|
project["compileTestJava"].doFirst { compileTask ->
|
28
|
-
println " (source =
|
28
|
+
println " (source = ${compileTask.source.asPath})"
|
29
29
|
}
|
30
30
|
}
|
31
31
|
|
@@ -75,7 +75,8 @@
|
|
75
75
|
"diamond",
|
76
76
|
"all-your-base",
|
77
77
|
"run-length-encoding",
|
78
|
-
"minesweeper"
|
78
|
+
"minesweeper",
|
79
|
+
"alphametics"
|
79
80
|
],
|
80
81
|
"exercises": [
|
81
82
|
{
|
@@ -151,30 +152,41 @@
|
|
151
152
|
"slug": "isogram",
|
152
153
|
"difficulty": 1,
|
153
154
|
"topics": [
|
155
|
+
"Strings",
|
156
|
+
"Filtering"
|
154
157
|
]
|
155
158
|
},
|
156
159
|
{
|
157
160
|
"slug": "beer-song",
|
158
161
|
"difficulty": 1,
|
159
162
|
"topics": [
|
163
|
+
"Looping",
|
164
|
+
"Conditionals",
|
165
|
+
"Strings"
|
160
166
|
]
|
161
167
|
},
|
162
168
|
{
|
163
169
|
"slug": "phone-number",
|
164
170
|
"difficulty": 1,
|
165
171
|
"topics": [
|
172
|
+
"Parsing",
|
173
|
+
"Transforming"
|
166
174
|
]
|
167
175
|
},
|
168
176
|
{
|
169
177
|
"slug": "anagram",
|
170
178
|
"difficulty": 1,
|
171
179
|
"topics": [
|
180
|
+
"Strings",
|
181
|
+
"Filtering"
|
172
182
|
]
|
173
183
|
},
|
174
184
|
{
|
175
185
|
"slug": "food-chain",
|
176
186
|
"difficulty": 1,
|
177
187
|
"topics": [
|
188
|
+
"Text formatting",
|
189
|
+
"Algorithms"
|
178
190
|
]
|
179
191
|
},
|
180
192
|
{
|
@@ -540,6 +552,14 @@
|
|
540
552
|
"arrays",
|
541
553
|
"algorithms"
|
542
554
|
]
|
555
|
+
},
|
556
|
+
{
|
557
|
+
"slug": "alphametics",
|
558
|
+
"difficulty": 7,
|
559
|
+
"topics": [
|
560
|
+
"games",
|
561
|
+
"algorithms"
|
562
|
+
]
|
543
563
|
}
|
544
564
|
],
|
545
565
|
"deprecated": [
|
@@ -0,0 +1,95 @@
|
|
1
|
+
var solve = require('./alphametics');
|
2
|
+
|
3
|
+
describe("Solve the alphametics puzzle", function() {
|
4
|
+
|
5
|
+
it("puzzle with three letters", function() {
|
6
|
+
var puzzle = "I + BB == ILL";
|
7
|
+
var expected = {
|
8
|
+
"I": 1,
|
9
|
+
"B": 9,
|
10
|
+
"L": 0
|
11
|
+
};
|
12
|
+
expect(solve(puzzle)).toEqual(expected);
|
13
|
+
});
|
14
|
+
|
15
|
+
xit("solution must have unique value for each letter", function() {
|
16
|
+
var puzzle = "A == B";
|
17
|
+
expect(solve(puzzle)).toBeNull();
|
18
|
+
});
|
19
|
+
|
20
|
+
xit("leading zero solution is invalid", function() {
|
21
|
+
var puzzle = "ACA + DD == BD";
|
22
|
+
expect(solve(puzzle)).toBeNull();
|
23
|
+
});
|
24
|
+
|
25
|
+
xit("puzzle with four letters", function() {
|
26
|
+
var puzzle = "AS + A == MOM";
|
27
|
+
var expected = {
|
28
|
+
"A": 9,
|
29
|
+
"S": 2,
|
30
|
+
"M": 1,
|
31
|
+
"O": 0
|
32
|
+
};
|
33
|
+
expect(solve(puzzle)).toEqual(expected);
|
34
|
+
});
|
35
|
+
|
36
|
+
xit("puzzle with six letters", function() {
|
37
|
+
var puzzle = "NO + NO + TOO == LATE";
|
38
|
+
var expected = {
|
39
|
+
"N": 7,
|
40
|
+
"O": 4,
|
41
|
+
"T": 9,
|
42
|
+
"L": 1,
|
43
|
+
"A": 0,
|
44
|
+
"E": 2
|
45
|
+
};
|
46
|
+
expect(solve(puzzle)).toEqual(expected);
|
47
|
+
});
|
48
|
+
|
49
|
+
xit("puzzle with seven letters", function() {
|
50
|
+
var puzzle = "HE + SEES + THE == LIGHT";
|
51
|
+
var expected = {
|
52
|
+
"E": 4,
|
53
|
+
"G": 2,
|
54
|
+
"H": 5,
|
55
|
+
"I": 0,
|
56
|
+
"L": 1,
|
57
|
+
"S": 9,
|
58
|
+
"T": 7
|
59
|
+
};
|
60
|
+
expect(solve(puzzle)).toEqual(expected);
|
61
|
+
});
|
62
|
+
|
63
|
+
xit("puzzle with eight letters", function() {
|
64
|
+
var puzzle = "SEND + MORE == MONEY";
|
65
|
+
var expected = {
|
66
|
+
"S": 9,
|
67
|
+
"E": 5,
|
68
|
+
"N": 6,
|
69
|
+
"D": 7,
|
70
|
+
"M": 1,
|
71
|
+
"O": 0,
|
72
|
+
"R": 8,
|
73
|
+
"Y": 2
|
74
|
+
};
|
75
|
+
expect(solve(puzzle)).toEqual(expected);
|
76
|
+
});
|
77
|
+
|
78
|
+
xit("puzzle with ten letters", function() {
|
79
|
+
var puzzle = "AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE";
|
80
|
+
var expected = {
|
81
|
+
"A": 5,
|
82
|
+
"D": 3,
|
83
|
+
"E": 4,
|
84
|
+
"F": 7,
|
85
|
+
"G": 8,
|
86
|
+
"N": 0,
|
87
|
+
"O": 2,
|
88
|
+
"R": 1,
|
89
|
+
"S": 6,
|
90
|
+
"T": 9
|
91
|
+
};
|
92
|
+
expect(solve(puzzle)).toEqual(expected);
|
93
|
+
});
|
94
|
+
|
95
|
+
});
|
@@ -0,0 +1,107 @@
|
|
1
|
+
function solve(puzzle) {
|
2
|
+
var parts = puzzle
|
3
|
+
.split(/[+|==]/g)
|
4
|
+
.map(function(o) { return o.trim(); })
|
5
|
+
.filter(function(o) { return o !== ""; });
|
6
|
+
|
7
|
+
if(parts.length < 3) {
|
8
|
+
return null;
|
9
|
+
}
|
10
|
+
|
11
|
+
var uniqueLetters = getUniqueLetters(parts.join(''));
|
12
|
+
var firstLetters = getFirstLetters(parts);
|
13
|
+
|
14
|
+
var numberCombinations = getNumberCombinations([0,1,2,3,4,5,6,7,8,9], uniqueLetters.length);
|
15
|
+
var permutations = getPermutations(Array(uniqueLetters.length).fill().map(function(_, i) {return i; }));
|
16
|
+
|
17
|
+
while(numberCombinations.length) {
|
18
|
+
var numberCombination = numberCombinations.pop();
|
19
|
+
for(var k = 0; k < permutations.length; k++) {
|
20
|
+
var newNumbers = assignNumbers(numberCombination, uniqueLetters, permutations[k]);
|
21
|
+
if(testNumbers(newNumbers, parts, firstLetters)) {
|
22
|
+
return newNumbers;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
return null;
|
27
|
+
}
|
28
|
+
|
29
|
+
function getFirstLetters(words) {
|
30
|
+
return words
|
31
|
+
.map(function(word) { return word[0]; })
|
32
|
+
.filter(function (val, i, arr) { return arr.indexOf(val) === i; });
|
33
|
+
}
|
34
|
+
|
35
|
+
function assignNumbers(numbers, letters, orders) {
|
36
|
+
var output = {};
|
37
|
+
for(var i = 0; i < letters.length; i++) {
|
38
|
+
output[letters[i]] = numbers[orders[i]];
|
39
|
+
}
|
40
|
+
return output;
|
41
|
+
}
|
42
|
+
|
43
|
+
function getUniqueLetters(string) {
|
44
|
+
return string.split('').filter(function (val, i, arr) { return arr.indexOf(val) === i; });
|
45
|
+
}
|
46
|
+
|
47
|
+
function testNumbers(numbers, puzzleParts, firstLetters) {
|
48
|
+
var keys = Object.keys(numbers);
|
49
|
+
for(var i = 0; i < keys.length; i++) {
|
50
|
+
if(numbers[keys[i]] === 0 && firstLetters.indexOf(keys[i]) !== -1) {
|
51
|
+
return false;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
var replaceRegex = new RegExp('[' + keys.join('') + ']', 'g');
|
55
|
+
|
56
|
+
puzzleParts = puzzleParts.join(',')
|
57
|
+
.replace(replaceRegex, function(input) { return numbers[input]; })
|
58
|
+
.split(',')
|
59
|
+
.map(function(t) {return parseInt(t);});
|
60
|
+
|
61
|
+
var total = puzzleParts.slice(puzzleParts.length-1)[0];
|
62
|
+
return total === puzzleParts
|
63
|
+
.slice(0,puzzleParts.length-1)
|
64
|
+
.reduce(function(acc, val) { return acc + val; },0);
|
65
|
+
}
|
66
|
+
|
67
|
+
function getPermutations(inputArr) {
|
68
|
+
var results = [];
|
69
|
+
function permute(arr, memo) {
|
70
|
+
var cur, memo = memo || [];
|
71
|
+
for (var i = 0; i < arr.length; i++) {
|
72
|
+
cur = arr.splice(i, 1);
|
73
|
+
if (arr.length === 0) {
|
74
|
+
results.push(memo.concat(cur));
|
75
|
+
}
|
76
|
+
permute(arr.slice(), memo.concat(cur));
|
77
|
+
arr.splice(i, 0, cur[0]);
|
78
|
+
}
|
79
|
+
return results;
|
80
|
+
}
|
81
|
+
return permute(inputArr);
|
82
|
+
}
|
83
|
+
|
84
|
+
function getNumberCombinations(set, k) {
|
85
|
+
var i, j, combs, head, tailcombs;
|
86
|
+
if (k > set.length || k <= 0) {
|
87
|
+
return [];
|
88
|
+
}
|
89
|
+
if (k === 1) {
|
90
|
+
combs = [];
|
91
|
+
for (i = 0; i < set.length; i++) {
|
92
|
+
combs.push([set[i]]);
|
93
|
+
}
|
94
|
+
return combs;
|
95
|
+
}
|
96
|
+
combs = [];
|
97
|
+
for (i = 0; i < set.length - k + 1; i++) {
|
98
|
+
head = set.slice(i, i + 1);
|
99
|
+
tailcombs = getNumberCombinations(set.slice(i + 1), k - 1);
|
100
|
+
for (j = 0; j < tailcombs.length; j++) {
|
101
|
+
combs.push(head.concat(tailcombs[j]));
|
102
|
+
}
|
103
|
+
}
|
104
|
+
return combs;
|
105
|
+
}
|
106
|
+
|
107
|
+
module.exports = solve;
|