trackler 2.2.0.0 → 2.2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/CONTRIBUTING.md +1 -1
- data/tracks/bash/.travis.yml +1 -1
- data/tracks/bash/config.json +30 -3
- data/tracks/c/README.md +1 -1
- data/tracks/c/config.json +131 -39
- data/tracks/ceylon/README.md +6 -6
- data/tracks/ceylon/config.json +21 -3
- data/tracks/chapel/.travis.yml +1 -1
- data/tracks/clojurescript/.travis.yml +1 -1
- data/tracks/clojurescript/README.md +6 -6
- data/tracks/clojurescript/exercises/.keep +0 -0
- data/tracks/coffeescript/.travis.yml +1 -1
- data/tracks/coldfusion/.travis.yml +1 -1
- data/tracks/coq/.travis.yml +1 -1
- data/tracks/cpp/CMakeLists.txt +1 -0
- data/tracks/cpp/README.md +1 -1
- data/tracks/cpp/config.json +8 -0
- data/tracks/cpp/exercises/atbash-cipher/CMakeLists.txt +52 -0
- data/tracks/cpp/exercises/atbash-cipher/atbash_cipher_test.cpp +68 -0
- data/tracks/cpp/exercises/atbash-cipher/example.cpp +54 -0
- data/tracks/cpp/exercises/atbash-cipher/example.h +13 -0
- data/tracks/csharp/config.json +315 -6
- data/tracks/d/.travis.yml +1 -1
- data/tracks/dart/README.md +2 -2
- data/tracks/dart/config.json +21 -3
- data/tracks/delphi/README.md +1 -1
- data/tracks/delphi/config.json +83 -1
- data/tracks/ecmascript/config.json +10 -0
- data/tracks/ecmascript/exercises/accumulate/accumulate.spec.js +3 -9
- data/tracks/ecmascript/exercises/acronym/acronym.spec.js +2 -2
- data/tracks/ecmascript/exercises/all-your-base/all-your-base.spec.js +131 -133
- data/tracks/ecmascript/exercises/all-your-base/example.js +1 -3
- data/tracks/ecmascript/exercises/allergies/allergies.spec.js +8 -10
- data/tracks/ecmascript/exercises/allergies/example.js +3 -5
- data/tracks/ecmascript/exercises/alphametics/alphametics.spec.js +61 -63
- data/tracks/ecmascript/exercises/alphametics/example.js +99 -99
- data/tracks/ecmascript/exercises/anagram/anagram.spec.js +35 -37
- data/tracks/ecmascript/exercises/anagram/example.js +1 -3
- data/tracks/ecmascript/exercises/atbash-cipher/atbash-cipher.spec.js +1 -3
- data/tracks/ecmascript/exercises/atbash-cipher/example.js +3 -3
- data/tracks/ecmascript/exercises/beer-song/beer-song.spec.js +0 -2
- data/tracks/ecmascript/exercises/beer-song/example.js +9 -9
- data/tracks/ecmascript/exercises/binary/binary.spec.js +1 -2
- data/tracks/ecmascript/exercises/binary/example.js +3 -3
- data/tracks/ecmascript/exercises/binary-search/binary-search.spec.js +1 -3
- data/tracks/ecmascript/exercises/binary-search-tree/binary-search-tree.spec.js +13 -15
- data/tracks/ecmascript/exercises/binary-search-tree/example.js +2 -2
- data/tracks/ecmascript/exercises/bob/bob.spec.js +1 -3
- data/tracks/ecmascript/exercises/bob/example.js +3 -3
- data/tracks/ecmascript/exercises/bracket-push/example.js +2 -2
- data/tracks/ecmascript/exercises/circular-buffer/circular-buffer.spec.js +10 -12
- data/tracks/ecmascript/exercises/circular-buffer/example.js +12 -11
- data/tracks/ecmascript/exercises/clock/clock.spec.js +0 -8
- data/tracks/ecmascript/exercises/clock/example.js +11 -11
- data/tracks/ecmascript/exercises/connect/connect.spec.js +75 -77
- data/tracks/ecmascript/exercises/connect/example.js +27 -29
- data/tracks/ecmascript/exercises/crypto-square/crypto-square.spec.js +11 -11
- data/tracks/ecmascript/exercises/crypto-square/example.js +11 -10
- data/tracks/ecmascript/exercises/custom-set/custom-set.spec.js +2 -4
- data/tracks/ecmascript/exercises/custom-set/example.js +1 -1
- data/tracks/ecmascript/exercises/diamond/diamond.spec.js +20 -21
- data/tracks/ecmascript/exercises/diamond/example.js +12 -13
- data/tracks/ecmascript/exercises/difference-of-squares/difference-of-squares.spec.js +0 -5
- data/tracks/ecmascript/exercises/diffie-hellman/diffie-hellman.spec.js +7 -28
- data/tracks/ecmascript/exercises/etl/etl.spec.js +36 -18
- data/tracks/ecmascript/exercises/etl/example.js +3 -3
- data/tracks/ecmascript/exercises/flatten-array/example.js +1 -1
- data/tracks/ecmascript/exercises/flatten-array/flatten-array.spec.js +2 -3
- data/tracks/ecmascript/exercises/food-chain/example.js +12 -12
- data/tracks/ecmascript/exercises/food-chain/food-chain.spec.js +0 -1
- data/tracks/ecmascript/exercises/gigasecond/example.js +1 -1
- data/tracks/ecmascript/exercises/gigasecond/gigasecond.spec.js +0 -1
- data/tracks/ecmascript/exercises/grade-school/grade-school.spec.js +18 -19
- data/tracks/ecmascript/exercises/grains/grains.spec.js +0 -1
- data/tracks/ecmascript/exercises/hamming/example.js +3 -3
- data/tracks/ecmascript/exercises/hamming/hamming.spec.js +5 -6
- data/tracks/ecmascript/exercises/hello-world/example.js +1 -1
- data/tracks/ecmascript/exercises/hello-world/hello-world.spec.js +1 -1
- data/tracks/ecmascript/exercises/hexadecimal/example.js +2 -2
- data/tracks/ecmascript/exercises/hexadecimal/hexadecimal.spec.js +9 -11
- data/tracks/ecmascript/exercises/isogram/isogram.spec.js +22 -23
- data/tracks/ecmascript/exercises/kindergarten-garden/example.js +7 -7
- data/tracks/ecmascript/exercises/kindergarten-garden/kindergarten-garden.spec.js +0 -5
- data/tracks/ecmascript/exercises/largest-series-product/example.js +4 -8
- data/tracks/ecmascript/exercises/largest-series-product/largest-series-product.spec.js +5 -7
- data/tracks/ecmascript/exercises/leap/leap.spec.js +4 -6
- data/tracks/ecmascript/exercises/linked-list/example.js +2 -2
- data/tracks/ecmascript/exercises/list-ops/example.js +19 -19
- data/tracks/ecmascript/exercises/list-ops/list-ops.spec.js +2 -18
- data/tracks/ecmascript/exercises/luhn/example.js +1 -1
- data/tracks/ecmascript/exercises/luhn/luhn.spec.js +1 -3
- data/tracks/ecmascript/exercises/matrix/example.js +2 -4
- data/tracks/ecmascript/exercises/matrix/matrix.spec.js +0 -2
- data/tracks/ecmascript/exercises/meetup/example.js +12 -15
- data/tracks/ecmascript/exercises/meetup/meetup.spec.js +0 -2
- data/tracks/ecmascript/exercises/minesweeper/example.js +60 -0
- data/tracks/ecmascript/exercises/minesweeper/minesweeper.spec.js +174 -0
- data/tracks/ecmascript/exercises/minesweeper/package.json +69 -0
- data/tracks/ecmascript/exercises/nth-prime/example.js +3 -2
- data/tracks/ecmascript/exercises/nth-prime/nth-prime.spec.js +0 -1
- data/tracks/ecmascript/exercises/ocr-numbers/example.js +3 -3
- data/tracks/ecmascript/exercises/ocr-numbers/ocr-numbers.spec.js +16 -18
- data/tracks/ecmascript/exercises/octal/example.js +1 -1
- data/tracks/ecmascript/exercises/octal/octal.spec.js +0 -2
- data/tracks/ecmascript/exercises/palindrome-products/example.js +14 -11
- data/tracks/ecmascript/exercises/palindrome-products/palindrome-products.spec.js +15 -18
- data/tracks/ecmascript/exercises/pangram/example.js +6 -5
- data/tracks/ecmascript/exercises/pangram/pangram.spec.js +10 -12
- data/tracks/ecmascript/exercises/pascals-triangle/example.js +2 -2
- data/tracks/ecmascript/exercises/pascals-triangle/pascals-triangle.spec.js +6 -8
- data/tracks/ecmascript/exercises/perfect-numbers/example.js +3 -5
- data/tracks/ecmascript/exercises/perfect-numbers/perfect-numbers.spec.js +0 -10
- data/tracks/ecmascript/exercises/phone-number/example.js +2 -2
- data/tracks/ecmascript/exercises/phone-number/phone-number.spec.js +0 -2
- data/tracks/ecmascript/exercises/pig-latin/example.js +4 -4
- data/tracks/ecmascript/exercises/pig-latin/pig-latin.spec.js +0 -1
- data/tracks/ecmascript/exercises/prime-factors/example.js +2 -2
- data/tracks/ecmascript/exercises/prime-factors/prime-factors.spec.js +0 -2
- data/tracks/ecmascript/exercises/pythagorean-triplet/pythagorean-triplet.spec.js +3 -11
- data/tracks/ecmascript/exercises/queen-attack/example.js +17 -17
- data/tracks/ecmascript/exercises/queen-attack/queen-attack.spec.js +7 -8
- data/tracks/ecmascript/exercises/raindrops/example.js +1 -1
- data/tracks/ecmascript/exercises/raindrops/raindrops.spec.js +1 -2
- data/tracks/ecmascript/exercises/rna-transcription/example.js +5 -5
- data/tracks/ecmascript/exercises/rna-transcription/rna-transcription.spec.js +4 -5
- data/tracks/ecmascript/exercises/robot-name/example.js +6 -6
- data/tracks/ecmascript/exercises/robot-name/robot-name.spec.js +10 -11
- data/tracks/ecmascript/exercises/robot-simulator/example.js +1 -1
- data/tracks/ecmascript/exercises/robot-simulator/robot-simulator.spec.js +31 -32
- data/tracks/ecmascript/exercises/roman-numerals/example.js +16 -16
- data/tracks/ecmascript/exercises/saddle-points/saddle-points.spec.js +3 -3
- data/tracks/ecmascript/exercises/say/example.js +25 -25
- data/tracks/ecmascript/exercises/say/say.spec.js +2 -3
- data/tracks/ecmascript/exercises/scrabble-score/example.js +27 -9
- data/tracks/ecmascript/exercises/scrabble-score/scrabble-score.spec.js +6 -7
- data/tracks/ecmascript/exercises/secret-handshake/example.js +2 -3
- data/tracks/ecmascript/exercises/secret-handshake/secret-handshake.spec.js +3 -5
- data/tracks/ecmascript/exercises/series/series.spec.js +1 -3
- data/tracks/ecmascript/exercises/sieve/example.js +4 -3
- data/tracks/ecmascript/exercises/sieve/sieve.spec.js +0 -2
- data/tracks/ecmascript/exercises/simple-cipher/example.js +8 -9
- data/tracks/ecmascript/exercises/simple-cipher/simple-cipher.spec.js +4 -4
- data/tracks/ecmascript/exercises/space-age/example.js +1 -1
- data/tracks/ecmascript/exercises/space-age/space-age.spec.js +9 -11
- data/tracks/ecmascript/exercises/strain/example.js +4 -4
- data/tracks/ecmascript/exercises/strain/strain.spec.js +14 -16
- data/tracks/ecmascript/exercises/sum-of-multiples/example.js +4 -4
- data/tracks/ecmascript/exercises/triangle/triangle.spec.js +2 -4
- data/tracks/ecmascript/exercises/trinary/example.js +3 -3
- data/tracks/ecmascript/exercises/trinary/trinary.spec.js +0 -2
- data/tracks/ecmascript/exercises/two-bucket/example.js +30 -27
- data/tracks/ecmascript/exercises/two-bucket/two-bucket.spec.js +4 -8
- data/tracks/ecmascript/exercises/word-count/example.js +2 -2
- data/tracks/ecmascript/exercises/word-count/word-count.spec.js +2 -3
- data/tracks/ecmascript/exercises/wordy/example.js +6 -6
- data/tracks/ecmascript/exercises/wordy/wordy.spec.js +2 -4
- data/tracks/factor/config.json +15 -6
- data/tracks/fortran/.travis.yml +1 -1
- data/tracks/fsharp/config.json +312 -10
- data/tracks/go/README.md +1 -1
- data/tracks/go/config.json +523 -155
- data/tracks/haskell/README.md +2 -2
- data/tracks/haskell/config.json +256 -7
- data/tracks/haxe/.travis.yml +1 -1
- data/tracks/haxe/Makefile +2 -2
- data/tracks/haxe/config.json +8 -5
- data/tracks/java/CONTRIBUTING.md +2 -2
- data/tracks/java/config.json +277 -17
- data/tracks/java/exercises/rotational-cipher/build.gradle +17 -0
- data/tracks/java/exercises/rotational-cipher/src/example/java/RotationalCipher.java +37 -0
- data/tracks/java/exercises/rotational-cipher/src/main/java/.keep +0 -0
- data/tracks/java/exercises/rotational-cipher/src/test/java/RotationalCipherTest.java +81 -0
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/java/exercises/twelve-days/src/main/java/TwelveDays.java +4 -0
- data/tracks/julia/.travis.yml +1 -1
- data/tracks/julia/README.md +1 -1
- data/tracks/kotlin/README.md +2 -2
- data/tracks/kotlin/exercises/hello-world/TUTORIAL.md +3 -3
- data/tracks/lisp/config.json +97 -3
- data/tracks/lisp/exercises/pascals-triangle/example.lisp +21 -0
- data/tracks/lisp/exercises/pascals-triangle/pascal.lisp +7 -0
- data/tracks/lisp/exercises/pascals-triangle/pascals-triangle-test.lisp +34 -0
- data/tracks/lua/.travis.yml +1 -1
- data/tracks/lua/README.md +1 -1
- data/tracks/mips/.travis.yml +1 -1
- data/tracks/mips/config.json +56 -17
- data/tracks/nasm/.travis.yml +1 -1
- data/tracks/nim/.travis.yml +1 -1
- data/tracks/ocaml/README.md +3 -3
- data/tracks/ocaml/config.json +130 -4
- data/tracks/perl5/docs/TESTS.md +40 -26
- data/tracks/plsql/.travis.yml +1 -1
- data/tracks/plsql/config.json +40 -13
- data/tracks/pony/.travis.yml +1 -1
- data/tracks/pony/bin/install-deps +4 -3
- data/tracks/prolog/.travis.yml +1 -1
- data/tracks/r/README.md +5 -5
- data/tracks/r/config.json +102 -30
- data/tracks/rust/.travis.yml +1 -1
- data/tracks/rust/config.json +172 -4
- data/tracks/rust/docs/EXERCISE_README_INSERT.md +1 -1
- data/tracks/sml/config.json +26 -3
- data/tracks/vimscript/config.json +60 -3
- metadata +16 -1
@@ -1,99 +1,99 @@
|
|
1
|
-
export default function solve(puzzle) {
|
2
|
-
|
3
|
-
.split(/[+|==]/g)
|
4
|
-
.map(o => o.trim())
|
5
|
-
.filter(o => o !==
|
6
|
-
|
7
|
-
if(parts.length < 3) {
|
8
|
-
return null;
|
9
|
-
}
|
10
|
-
|
11
|
-
const uniqueLetters = new Set(parts.join('').split(''));
|
12
|
-
const firstLetters = new Set(parts.map(p => p[0]));
|
13
|
-
|
14
|
-
const numberCombinations = getNumberCombinations([0,1,2,3,4,5,6,7,8,9], uniqueLetters.size);
|
15
|
-
|
16
|
-
while(numberCombinations.length) {
|
17
|
-
const permutations = generate(Array(uniqueLetters.size).fill().map((_, i) => i));
|
18
|
-
const numberCombination = numberCombinations.pop();
|
19
|
-
for(const permutation of permutations) {
|
20
|
-
const newNumbers = assignNumbers(numberCombination, uniqueLetters, permutation);
|
21
|
-
if(testNumbers(newNumbers, parts, firstLetters)) {
|
22
|
-
return newNumbers;
|
23
|
-
}
|
24
|
-
}
|
25
|
-
}
|
26
|
-
return null;
|
27
|
-
}
|
28
|
-
|
29
|
-
function assignNumbers(numberCombination, uniqueLetters, permutation) {
|
30
|
-
|
31
|
-
let i = 0;
|
32
|
-
for(
|
33
|
-
output[letter] = numberCombination[permutation[i++]];
|
34
|
-
}
|
35
|
-
return output;
|
36
|
-
}
|
37
|
-
|
38
|
-
function testNumbers(numbers, puzzleParts, firstLetters) {
|
39
|
-
|
40
|
-
for(const key of keys) {
|
41
|
-
if(numbers[key] === 0 && firstLetters.has(key)) {
|
42
|
-
return false;
|
43
|
-
}
|
44
|
-
}
|
45
|
-
|
46
|
-
|
47
|
-
puzzleParts = puzzleParts.join(',')
|
48
|
-
.replace(replaceRegex, input => numbers[input])
|
49
|
-
.split(',')
|
50
|
-
.map(t => parseInt(t));
|
51
|
-
|
52
|
-
|
53
|
-
return total === puzzleParts
|
54
|
-
.slice(0,puzzleParts.length-1)
|
55
|
-
.reduce((acc, val) => acc + val, 0);
|
56
|
-
}
|
57
|
-
function* generate(A) {
|
58
|
-
|
59
|
-
|
60
|
-
yield A;
|
61
|
-
for(let i = 0; i < n; i++) {
|
62
|
-
c[i] = 0;
|
63
|
-
}
|
64
|
-
let i = 0;
|
65
|
-
while(i < n) {
|
66
|
-
if(c[i] < i) {
|
67
|
-
if(i % 2 === 0) {
|
68
|
-
swap(A, 0, i);
|
69
|
-
} else {
|
70
|
-
swap(A, c[i], i);
|
71
|
-
}
|
72
|
-
yield A;
|
73
|
-
c[i]+=1;
|
74
|
-
i = 0;
|
75
|
-
} else {
|
76
|
-
c[i] = 0;
|
77
|
-
i+= 1;
|
78
|
-
}
|
79
|
-
}
|
80
|
-
}
|
81
|
-
function swap(list, x, y) {
|
82
|
-
|
83
|
-
list[x] = list[y];
|
84
|
-
list[y] = tmp;
|
85
|
-
return list;
|
86
|
-
}
|
87
|
-
|
88
|
-
function getNumberCombinations(arr, size) {
|
89
|
-
|
90
|
-
|
91
|
-
if (size == len) return [arr];
|
92
|
-
|
93
|
-
return arr.reduce((acc, val, i) => {
|
94
|
-
|
95
|
-
.map(comb => [val].concat(comb));
|
96
|
-
|
97
|
-
return acc.concat(res);
|
98
|
-
}, []);
|
99
|
-
}
|
1
|
+
export default function solve(puzzle) {
|
2
|
+
const parts = puzzle
|
3
|
+
.split(/[+|==]/g)
|
4
|
+
.map(o => o.trim())
|
5
|
+
.filter(o => o !== '');
|
6
|
+
|
7
|
+
if (parts.length < 3) {
|
8
|
+
return null;
|
9
|
+
}
|
10
|
+
|
11
|
+
const uniqueLetters = new Set(parts.join('').split(''));
|
12
|
+
const firstLetters = new Set(parts.map(p => p[0]));
|
13
|
+
|
14
|
+
const numberCombinations = getNumberCombinations([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], uniqueLetters.size);
|
15
|
+
|
16
|
+
while (numberCombinations.length) {
|
17
|
+
const permutations = generate(Array(uniqueLetters.size).fill().map((_, i) => i));
|
18
|
+
const numberCombination = numberCombinations.pop();
|
19
|
+
for (const permutation of permutations) {
|
20
|
+
const newNumbers = assignNumbers(numberCombination, uniqueLetters, permutation);
|
21
|
+
if (testNumbers(newNumbers, parts, firstLetters)) {
|
22
|
+
return newNumbers;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
return null;
|
27
|
+
}
|
28
|
+
|
29
|
+
function assignNumbers(numberCombination, uniqueLetters, permutation) {
|
30
|
+
const output = {};
|
31
|
+
let i = 0;
|
32
|
+
for (const letter of uniqueLetters.values()) {
|
33
|
+
output[letter] = numberCombination[permutation[i++]];
|
34
|
+
}
|
35
|
+
return output;
|
36
|
+
}
|
37
|
+
|
38
|
+
function testNumbers(numbers, puzzleParts, firstLetters) {
|
39
|
+
const keys = Object.keys(numbers);
|
40
|
+
for (const key of keys) {
|
41
|
+
if (numbers[key] === 0 && firstLetters.has(key)) {
|
42
|
+
return false;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
const replaceRegex = new RegExp(`[${keys.join('')}]`, 'g');
|
46
|
+
|
47
|
+
puzzleParts = puzzleParts.join(',')
|
48
|
+
.replace(replaceRegex, input => numbers[input])
|
49
|
+
.split(',')
|
50
|
+
.map(t => parseInt(t));
|
51
|
+
|
52
|
+
const total = puzzleParts.slice(puzzleParts.length - 1)[0];
|
53
|
+
return total === puzzleParts
|
54
|
+
.slice(0, puzzleParts.length - 1)
|
55
|
+
.reduce((acc, val) => acc + val, 0);
|
56
|
+
}
|
57
|
+
function* generate(A) {
|
58
|
+
const c = [];
|
59
|
+
const n = A.length;
|
60
|
+
yield A;
|
61
|
+
for (let i = 0; i < n; i++) {
|
62
|
+
c[i] = 0;
|
63
|
+
}
|
64
|
+
let i = 0;
|
65
|
+
while (i < n) {
|
66
|
+
if (c[i] < i) {
|
67
|
+
if (i % 2 === 0) {
|
68
|
+
swap(A, 0, i);
|
69
|
+
} else {
|
70
|
+
swap(A, c[i], i);
|
71
|
+
}
|
72
|
+
yield A;
|
73
|
+
c[i] += 1;
|
74
|
+
i = 0;
|
75
|
+
} else {
|
76
|
+
c[i] = 0;
|
77
|
+
i += 1;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
function swap(list, x, y) {
|
82
|
+
const tmp = list[x];
|
83
|
+
list[x] = list[y];
|
84
|
+
list[y] = tmp;
|
85
|
+
return list;
|
86
|
+
}
|
87
|
+
|
88
|
+
function getNumberCombinations(arr, size) {
|
89
|
+
const len = arr.length;
|
90
|
+
|
91
|
+
if (size == len) return [arr];
|
92
|
+
|
93
|
+
return arr.reduce((acc, val, i) => {
|
94
|
+
const res = getNumberCombinations(arr.slice(i + 1), size - 1)
|
95
|
+
.map(comb => [val].concat(comb));
|
96
|
+
|
97
|
+
return acc.concat(res);
|
98
|
+
}, []);
|
99
|
+
}
|
@@ -1,82 +1,80 @@
|
|
1
1
|
import Anagram from './anagram.js';
|
2
2
|
|
3
3
|
describe('Anagram', () => {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
let matches = subject.matches([ "hello", "world", "zombies", "pants"]);
|
4
|
+
test('no matches', () => {
|
5
|
+
const subject = new Anagram('diaper');
|
6
|
+
const matches = subject.matches(['hello', 'world', 'zombies', 'pants']);
|
8
7
|
|
9
8
|
expect(matches).toEqual([]);
|
10
9
|
});
|
11
10
|
|
12
|
-
xtest(
|
13
|
-
|
14
|
-
|
11
|
+
xtest('detects simple anagram', () => {
|
12
|
+
const subject = new Anagram('ant');
|
13
|
+
const matches = subject.matches(['tan', 'stand', 'at']);
|
15
14
|
|
16
15
|
expect(matches).toEqual(['tan']);
|
17
16
|
});
|
18
17
|
|
19
|
-
xtest(
|
20
|
-
|
21
|
-
|
18
|
+
xtest('does not detect false positives', () => {
|
19
|
+
const subject = new Anagram('galea');
|
20
|
+
const matches = subject.matches(['eagle']);
|
22
21
|
|
23
22
|
expect(matches).toEqual([]);
|
24
23
|
});
|
25
24
|
|
26
|
-
xtest(
|
27
|
-
|
28
|
-
|
25
|
+
xtest('detects multiple anagrams', () => {
|
26
|
+
const subject = new Anagram('master');
|
27
|
+
const matches = subject.matches(['stream', 'pigeon', 'maters']);
|
29
28
|
|
30
29
|
expect(matches).toEqual(['stream', 'maters']);
|
31
30
|
});
|
32
31
|
|
33
|
-
xtest(
|
34
|
-
|
35
|
-
|
32
|
+
xtest('does not detect anagram subsets', () => {
|
33
|
+
const subject = new Anagram('good');
|
34
|
+
const matches = subject.matches(['dog', 'goody']);
|
36
35
|
|
37
36
|
expect(matches).toEqual([]);
|
38
37
|
});
|
39
38
|
|
40
|
-
xtest(
|
41
|
-
|
42
|
-
|
39
|
+
xtest('detects anagram', () => {
|
40
|
+
const subject = new Anagram('listen');
|
41
|
+
const matches = subject.matches(['enlists', 'google', 'inlets', 'banana']);
|
43
42
|
|
44
43
|
expect(matches).toEqual(['inlets']);
|
45
44
|
});
|
46
45
|
|
47
|
-
xtest(
|
48
|
-
|
49
|
-
|
46
|
+
xtest('detects multiple anagrams', () => {
|
47
|
+
const subject = new Anagram('allergy');
|
48
|
+
const matches = subject.matches(['gallery', 'ballerina', 'regally', 'clergy', 'largely', 'leading']);
|
50
49
|
|
51
50
|
expect(matches).toEqual(['gallery', 'regally', 'largely']);
|
52
51
|
});
|
53
52
|
|
54
|
-
xtest(
|
55
|
-
|
56
|
-
|
53
|
+
xtest('detects anagrams case-insensitively', () => {
|
54
|
+
const subject = new Anagram('Orchestra');
|
55
|
+
const matches = subject.matches(['cashregister', 'Carthorse', 'radishes']);
|
57
56
|
|
58
57
|
expect(matches).toEqual(['Carthorse']);
|
59
58
|
});
|
60
59
|
|
61
|
-
xtest(
|
62
|
-
|
63
|
-
|
60
|
+
xtest('does not detect a word as its own anagram', () => {
|
61
|
+
const subject = new Anagram('banana');
|
62
|
+
const matches = subject.matches(['Banana']);
|
64
63
|
|
65
64
|
expect(matches).toEqual([]);
|
66
65
|
});
|
67
66
|
|
68
|
-
xtest(
|
69
|
-
|
70
|
-
|
67
|
+
xtest('matches() accepts string arguments', () => {
|
68
|
+
const subject = new Anagram('ant');
|
69
|
+
const matches = subject.matches('stand', 'tan', 'at');
|
71
70
|
|
72
|
-
expect(matches).toEqual([
|
71
|
+
expect(matches).toEqual(['tan']);
|
73
72
|
});
|
74
73
|
|
75
|
-
xtest(
|
76
|
-
|
77
|
-
|
74
|
+
xtest('matches() accepts single string argument', () => {
|
75
|
+
const subject = new Anagram('ant');
|
76
|
+
const matches = subject.matches('tan');
|
78
77
|
|
79
|
-
expect(matches).toEqual([
|
78
|
+
expect(matches).toEqual(['tan']);
|
80
79
|
});
|
81
|
-
|
82
80
|
});
|
@@ -15,9 +15,7 @@ export default class Anagram {
|
|
15
15
|
matches(words) {
|
16
16
|
words = Array.isArray(words) ? words : Array.from(arguments);
|
17
17
|
|
18
|
-
return words.filter(candidate =>
|
19
|
-
return !sameWord(this.word, candidate) && isAnagram(this.word, candidate);
|
20
|
-
});
|
18
|
+
return words.filter(candidate => !sameWord(this.word, candidate) && isAnagram(this.word, candidate));
|
21
19
|
}
|
22
20
|
}
|
23
21
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import atbash from './atbash-cipher';
|
2
2
|
|
3
3
|
describe('encode', () => {
|
4
|
-
|
5
4
|
test('encodes no', () => expect(atbash.encode('no')).toEqual('ml'));
|
6
5
|
|
7
6
|
xtest('encodes yes', () => expect(atbash.encode('yes')).toEqual('bvh'));
|
@@ -18,7 +17,6 @@ describe('encode', () => {
|
|
18
17
|
xtest('encodes sentences', () => expect(atbash.encode('Truth is fiction.')).toEqual('gifgs rhurx grlm'));
|
19
18
|
|
20
19
|
xtest('encodes all the things', () => expect(atbash.encode('The quick brown fox jumps over the lazy dog.'))
|
21
|
-
.toEqual('gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt')
|
20
|
+
.toEqual('gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt'),
|
22
21
|
);
|
23
|
-
|
24
22
|
});
|
@@ -2,7 +2,7 @@ const LETTERS = 'abcdefghijklmnopqrstuvwxyz';
|
|
2
2
|
const REVERSED_LETTERS = [...LETTERS].reverse().join('');
|
3
3
|
|
4
4
|
function insertSpacing(s, interval) {
|
5
|
-
const matcher = new RegExp(
|
5
|
+
const matcher = new RegExp(`.{1,${interval}}`, 'g');
|
6
6
|
return s.match(matcher).join(' ');
|
7
7
|
}
|
8
8
|
|
@@ -15,11 +15,11 @@ function invert(character) {
|
|
15
15
|
}
|
16
16
|
|
17
17
|
export default {
|
18
|
-
encode:
|
18
|
+
encode: (s) => {
|
19
19
|
let encoded;
|
20
20
|
const characters = [];
|
21
21
|
[...s.toLowerCase()].forEach(invert, characters);
|
22
22
|
encoded = insertSpacing(characters.join(''), 5);
|
23
23
|
return encoded;
|
24
|
-
}
|
24
|
+
},
|
25
25
|
};
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import Beer from './beer-song';
|
2
2
|
|
3
3
|
describe('Beer', () => {
|
4
|
-
|
5
4
|
test('prints an arbitrary verse', () => {
|
6
5
|
const expected = `8 bottles of beer on the wall, 8 bottles of beer.
|
7
6
|
Take one down and pass it around, 7 bottles of beer on the wall.
|
@@ -356,5 +355,4 @@ No more bottles of beer on the wall, no more bottles of beer.
|
|
356
355
|
Go to the store and buy some more, 99 bottles of beer on the wall.
|
357
356
|
`);
|
358
357
|
});
|
359
|
-
|
360
358
|
});
|
@@ -7,7 +7,7 @@ function bottles(number) {
|
|
7
7
|
return '1 bottle';
|
8
8
|
}
|
9
9
|
|
10
|
-
return number
|
10
|
+
return `${number} bottles`;
|
11
11
|
}
|
12
12
|
|
13
13
|
function action(currentVerse) {
|
@@ -15,12 +15,12 @@ function action(currentVerse) {
|
|
15
15
|
return 'Go to the store and buy some more, ';
|
16
16
|
}
|
17
17
|
|
18
|
-
|
19
|
-
return
|
18
|
+
const sbj = currentVerse === 1 ? 'it' : 'one';
|
19
|
+
return `Take ${sbj} down and pass it around, `;
|
20
20
|
}
|
21
21
|
|
22
22
|
function nextBottle(currentVerse) {
|
23
|
-
return bottles(nextVerse(currentVerse)).toLowerCase()
|
23
|
+
return `${bottles(nextVerse(currentVerse)).toLowerCase()} of beer on the wall.\n`;
|
24
24
|
}
|
25
25
|
|
26
26
|
function nextVerse(currentVerse) {
|
@@ -29,16 +29,16 @@ function nextVerse(currentVerse) {
|
|
29
29
|
|
30
30
|
class BeerSong {
|
31
31
|
static verse(number) {
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
const line1 = `${bottles(number)} of beer on the wall, `;
|
33
|
+
const line2 = `${bottles(number).toLowerCase()} of beer.\n`;
|
34
|
+
const line3 = action(number);
|
35
|
+
const line4 = nextBottle(number);
|
36
36
|
|
37
37
|
return [line1, line2, line3, line4].join('');
|
38
38
|
}
|
39
39
|
|
40
40
|
static sing(first = 99, last = 0) {
|
41
|
-
|
41
|
+
const verses = [];
|
42
42
|
for (let i = first; i >= last; i--) {
|
43
43
|
verses.push(this.verse(i));
|
44
44
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import Binary from'./binary';
|
1
|
+
import Binary from './binary';
|
2
2
|
|
3
3
|
describe('binary', () => {
|
4
4
|
test('0 is decimal 0', () => expect(new Binary('0').toDecimal()).toEqual(0));
|
@@ -26,5 +26,4 @@ describe('binary', () => {
|
|
26
26
|
expect(new Binary('nope10').toDecimal()).toEqual(0);
|
27
27
|
expect(new Binary('10nope10').toDecimal()).toEqual(0);
|
28
28
|
});
|
29
|
-
|
30
29
|
});
|
@@ -1,12 +1,11 @@
|
|
1
1
|
import BinarySearch from './binary-search';
|
2
2
|
|
3
3
|
describe('BinarySearch', () => {
|
4
|
-
|
5
4
|
const sortedArray = [1, 2, 3, 4, 5, 6];
|
6
5
|
const sortedArrayOfOddLength = [0, 1, 2, 2, 3, 10, 12];
|
7
6
|
const unsortedArray = [10, 2, 5, 1];
|
8
7
|
|
9
|
-
it
|
8
|
+
it('should require a sorted array', () => {
|
10
9
|
const invalidBinarySearch = new BinarySearch(unsortedArray);
|
11
10
|
const validBinarySearch = new BinarySearch(sortedArray);
|
12
11
|
|
@@ -25,6 +24,5 @@ describe('BinarySearch', () => {
|
|
25
24
|
xtest('should return -1 for a value not in the array', () => {
|
26
25
|
expect(new BinarySearch(sortedArray).indexOf(10)).toEqual(-1);
|
27
26
|
});
|
28
|
-
|
29
27
|
});
|
30
28
|
|
@@ -1,21 +1,20 @@
|
|
1
1
|
import BinarySearchTree from './binary-search-tree';
|
2
2
|
|
3
3
|
function recordAllData(bst) {
|
4
|
-
|
4
|
+
const out = [];
|
5
5
|
|
6
|
-
bst.each(
|
6
|
+
bst.each(data => out.push(data));
|
7
7
|
|
8
8
|
return out;
|
9
9
|
}
|
10
10
|
|
11
11
|
describe('BinarySearchTree', () => {
|
12
|
-
|
13
12
|
test('data is retained', () => {
|
14
13
|
expect(new BinarySearchTree(4).data).toEqual(4);
|
15
14
|
});
|
16
15
|
|
17
16
|
xtest('inserting less', () => {
|
18
|
-
|
17
|
+
const four = new BinarySearchTree(4);
|
19
18
|
four.insert(2);
|
20
19
|
|
21
20
|
expect(four.data).toEqual(4);
|
@@ -23,7 +22,7 @@ describe('BinarySearchTree', () => {
|
|
23
22
|
});
|
24
23
|
|
25
24
|
xtest('inserting same', () => {
|
26
|
-
|
25
|
+
const four = new BinarySearchTree(4);
|
27
26
|
four.insert(4);
|
28
27
|
|
29
28
|
expect(four.data).toEqual(4);
|
@@ -31,7 +30,7 @@ describe('BinarySearchTree', () => {
|
|
31
30
|
});
|
32
31
|
|
33
32
|
xtest('inserting right', () => {
|
34
|
-
|
33
|
+
const four = new BinarySearchTree(4);
|
35
34
|
four.insert(5);
|
36
35
|
|
37
36
|
expect(four.data).toEqual(4);
|
@@ -39,7 +38,7 @@ describe('BinarySearchTree', () => {
|
|
39
38
|
});
|
40
39
|
|
41
40
|
xtest('complex tree', () => {
|
42
|
-
|
41
|
+
const four = new BinarySearchTree(4);
|
43
42
|
four.insert(2);
|
44
43
|
four.insert(6);
|
45
44
|
four.insert(1);
|
@@ -57,25 +56,25 @@ describe('BinarySearchTree', () => {
|
|
57
56
|
});
|
58
57
|
|
59
58
|
xtest('iterating one element', () => {
|
60
|
-
expect(recordAllData(new BinarySearchTree(4))).toEqual([
|
59
|
+
expect(recordAllData(new BinarySearchTree(4))).toEqual([4]);
|
61
60
|
});
|
62
61
|
|
63
62
|
xtest('iterating over smaller element', () => {
|
64
|
-
|
63
|
+
const four = new BinarySearchTree(4);
|
65
64
|
four.insert(2);
|
66
65
|
|
67
|
-
expect(recordAllData(four)).toEqual([
|
66
|
+
expect(recordAllData(four)).toEqual([2, 4]);
|
68
67
|
});
|
69
68
|
|
70
69
|
xtest('iterating over larger element', () => {
|
71
|
-
|
70
|
+
const four = new BinarySearchTree(4);
|
72
71
|
four.insert(5);
|
73
72
|
|
74
|
-
expect(recordAllData(four)).toEqual([
|
73
|
+
expect(recordAllData(four)).toEqual([4, 5]);
|
75
74
|
});
|
76
75
|
|
77
76
|
xtest('iterating over complex tree', () => {
|
78
|
-
|
77
|
+
const four = new BinarySearchTree(4);
|
79
78
|
four.insert(2);
|
80
79
|
four.insert(1);
|
81
80
|
four.insert(3);
|
@@ -83,7 +82,6 @@ describe('BinarySearchTree', () => {
|
|
83
82
|
four.insert(7);
|
84
83
|
four.insert(5);
|
85
84
|
|
86
|
-
expect(recordAllData(four)).toEqual([
|
85
|
+
expect(recordAllData(four)).toEqual([1, 2, 3, 4, 5, 6, 7]);
|
87
86
|
});
|
88
|
-
|
89
87
|
});
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import Bob from './bob.js';
|
2
2
|
|
3
3
|
describe('Bob', () => {
|
4
|
-
|
5
4
|
const bob = new Bob();
|
6
5
|
|
7
6
|
test('stating something', () => {
|
@@ -84,10 +83,9 @@ describe('Bob', () => {
|
|
84
83
|
expect(result).toEqual('Fine. Be that way!');
|
85
84
|
});
|
86
85
|
|
87
|
-
|
86
|
+
xtest('prolonged silence', () => {
|
88
87
|
const result = bob.hey(' ');
|
89
88
|
expect(result).toEqual('Fine. Be that way!');
|
90
89
|
});
|
91
|
-
|
92
90
|
});
|
93
91
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
const isSilence = message => message.replace(/\s+/g, '') === '';
|
2
|
+
const isShouting = message => message.toUpperCase() === message && /[A-Z]/.test(message);
|
3
|
+
const isAQuestion = message => message[message.length - 1] === '?';
|
4
4
|
|
5
5
|
class Bob {
|
6
6
|
hey(message) {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
const bracketPush = input =>
|
1
|
+
const bracketPush = (input) => {
|
2
2
|
if (input.length === 0) {
|
3
3
|
return true;
|
4
4
|
}
|
@@ -20,7 +20,7 @@ const bracketPush = input => {
|
|
20
20
|
}
|
21
21
|
}
|
22
22
|
|
23
|
-
const topNumber = Math.max
|
23
|
+
const topNumber = Math.max(...iArr);
|
24
24
|
|
25
25
|
for (let k = 0; k < 3; k++) {
|
26
26
|
if (bracketArray[topNumber] === openArray[k]) {
|