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
@@ -0,0 +1,60 @@
|
|
1
|
+
const MINE = '*';
|
2
|
+
|
3
|
+
const DELTAS = [
|
4
|
+
[-1, -1],
|
5
|
+
[-1, 0],
|
6
|
+
[-1, 1],
|
7
|
+
[1, 1],
|
8
|
+
[1, 0],
|
9
|
+
[1, -1],
|
10
|
+
[0, 1],
|
11
|
+
[0, -1],
|
12
|
+
];
|
13
|
+
|
14
|
+
class Minesweeper {
|
15
|
+
annotate(rows) {
|
16
|
+
if (noDataPresent(rows)) {
|
17
|
+
return rows;
|
18
|
+
}
|
19
|
+
|
20
|
+
const inputBoard = rows.map(row => [...row]);
|
21
|
+
|
22
|
+
return stringify(
|
23
|
+
inputBoard.map((row, x) => [...row].map((cell, y) => cellToMineOrCount(cell, inputBoard, x, y))),
|
24
|
+
);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
function cellToMineOrCount(cell, inputBoard, x, y) {
|
29
|
+
if (cell === MINE) {
|
30
|
+
return MINE;
|
31
|
+
}
|
32
|
+
return countAdjacentMines(inputBoard, x, y) || " ";
|
33
|
+
|
34
|
+
}
|
35
|
+
|
36
|
+
function countAdjacentMines(board, x, y) {
|
37
|
+
return DELTAS
|
38
|
+
.filter(d => adjacentSquareIsOnBoard(board, x, d))
|
39
|
+
.filter(d => adjacentSquareHasMine(board, x, y, d))
|
40
|
+
.length;
|
41
|
+
}
|
42
|
+
|
43
|
+
function stringify(board) {
|
44
|
+
return board.map(row => row.join(''));
|
45
|
+
}
|
46
|
+
|
47
|
+
function noDataPresent(rows) {
|
48
|
+
return rows.length === 0 || rows[0].length === 0;
|
49
|
+
}
|
50
|
+
|
51
|
+
function adjacentSquareIsOnBoard(board, x, d) {
|
52
|
+
return board[x + d[0]];
|
53
|
+
}
|
54
|
+
|
55
|
+
function adjacentSquareHasMine(board, x, y, d) {
|
56
|
+
return board[x + d[0]][y + d[1]] === MINE;
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
export default Minesweeper;
|
@@ -0,0 +1,174 @@
|
|
1
|
+
import Minesweeper from './minesweeper';
|
2
|
+
|
3
|
+
|
4
|
+
describe('Minesweeper()', () => {
|
5
|
+
let minesweeper;
|
6
|
+
|
7
|
+
beforeEach(() => {
|
8
|
+
minesweeper = new Minesweeper();
|
9
|
+
});
|
10
|
+
|
11
|
+
test('handles no rows', () => {
|
12
|
+
expect(minesweeper.annotate([])).toEqual([]);
|
13
|
+
});
|
14
|
+
|
15
|
+
xtest('handles no columns', () => {
|
16
|
+
expect(minesweeper.annotate([''])).toEqual(['']);
|
17
|
+
});
|
18
|
+
|
19
|
+
xtest('handles no mines', () => {
|
20
|
+
const input = [
|
21
|
+
' ',
|
22
|
+
' ',
|
23
|
+
' ',
|
24
|
+
];
|
25
|
+
const expected = [
|
26
|
+
' ',
|
27
|
+
' ',
|
28
|
+
' ',
|
29
|
+
];
|
30
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
31
|
+
});
|
32
|
+
|
33
|
+
xtest('handles board with only mines', () => {
|
34
|
+
const input = [
|
35
|
+
'***',
|
36
|
+
'***',
|
37
|
+
'***',
|
38
|
+
];
|
39
|
+
const expected = [
|
40
|
+
'***',
|
41
|
+
'***',
|
42
|
+
'***',
|
43
|
+
];
|
44
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
45
|
+
});
|
46
|
+
|
47
|
+
xtest('handles mine surrounded by spaces', () => {
|
48
|
+
const input = [
|
49
|
+
' ',
|
50
|
+
' * ',
|
51
|
+
' ',
|
52
|
+
];
|
53
|
+
const expected = [
|
54
|
+
'111',
|
55
|
+
'1*1',
|
56
|
+
'111',
|
57
|
+
];
|
58
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
59
|
+
});
|
60
|
+
|
61
|
+
xtest('handles space surrounded by mines', () => {
|
62
|
+
const input = [
|
63
|
+
'***',
|
64
|
+
'* *',
|
65
|
+
'***',
|
66
|
+
];
|
67
|
+
const expected = [
|
68
|
+
'***',
|
69
|
+
'*8*',
|
70
|
+
'***',
|
71
|
+
];
|
72
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
73
|
+
});
|
74
|
+
|
75
|
+
xtest('handles space surrounded by mines', () => {
|
76
|
+
const input = [
|
77
|
+
'***',
|
78
|
+
'* *',
|
79
|
+
'***',
|
80
|
+
];
|
81
|
+
const expected = [
|
82
|
+
'***',
|
83
|
+
'*8*',
|
84
|
+
'***',
|
85
|
+
];
|
86
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
87
|
+
});
|
88
|
+
|
89
|
+
xtest('handles horizontal line', () => {
|
90
|
+
const input = [' * * '];
|
91
|
+
const expected = ['1*2*1'];
|
92
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
93
|
+
});
|
94
|
+
|
95
|
+
xtest('handles horizontal line, mines at edges', () => {
|
96
|
+
const input = ['* *'];
|
97
|
+
const expected = ['*1 1*'];
|
98
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
99
|
+
});
|
100
|
+
|
101
|
+
xtest('handles vertical line', () => {
|
102
|
+
const input = [
|
103
|
+
' ',
|
104
|
+
'*',
|
105
|
+
' ',
|
106
|
+
'*',
|
107
|
+
' ',
|
108
|
+
];
|
109
|
+
const expected = [
|
110
|
+
'1',
|
111
|
+
'*',
|
112
|
+
'2',
|
113
|
+
'*',
|
114
|
+
'1',
|
115
|
+
];
|
116
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
117
|
+
});
|
118
|
+
|
119
|
+
xtest('handles vertical line, mines at edges', () => {
|
120
|
+
const input = [
|
121
|
+
'*',
|
122
|
+
' ',
|
123
|
+
' ',
|
124
|
+
' ',
|
125
|
+
'*',
|
126
|
+
];
|
127
|
+
const expected = [
|
128
|
+
'*',
|
129
|
+
'1',
|
130
|
+
' ',
|
131
|
+
'1',
|
132
|
+
'*',
|
133
|
+
];
|
134
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
135
|
+
});
|
136
|
+
|
137
|
+
xtest('handles cross', () => {
|
138
|
+
const input = [
|
139
|
+
' * ',
|
140
|
+
' * ',
|
141
|
+
'*****',
|
142
|
+
' * ',
|
143
|
+
' * ',
|
144
|
+
];
|
145
|
+
const expected = [
|
146
|
+
' 2*2 ',
|
147
|
+
'25*52',
|
148
|
+
'*****',
|
149
|
+
'25*52',
|
150
|
+
' 2*2 ',
|
151
|
+
];
|
152
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
153
|
+
});
|
154
|
+
|
155
|
+
xtest('handles large board', () => {
|
156
|
+
const input = [
|
157
|
+
' * * ',
|
158
|
+
' * ',
|
159
|
+
' * ',
|
160
|
+
' * *',
|
161
|
+
' * * ',
|
162
|
+
' ',
|
163
|
+
];
|
164
|
+
const expected = [
|
165
|
+
'1*22*1',
|
166
|
+
'12*322',
|
167
|
+
' 123*2',
|
168
|
+
'112*4*',
|
169
|
+
'1*22*2',
|
170
|
+
'111111',
|
171
|
+
];
|
172
|
+
expect(minesweeper.annotate(input)).toEqual(expected);
|
173
|
+
});
|
174
|
+
});
|
@@ -0,0 +1,69 @@
|
|
1
|
+
{
|
2
|
+
"name": "xecmascript",
|
3
|
+
"version": "0.0.0",
|
4
|
+
"description": "Exercism exercises in ECMAScript 6.",
|
5
|
+
"author": "Katrina Owen",
|
6
|
+
"private": true,
|
7
|
+
"repository": {
|
8
|
+
"type": "git",
|
9
|
+
"url": "https://github.com/exercism/xecmascript"
|
10
|
+
},
|
11
|
+
"devDependencies": {
|
12
|
+
"babel-jest": "^20.0.1",
|
13
|
+
"babel-plugin-transform-builtin-extend": "^1.1.2",
|
14
|
+
"babel-preset-env": "^1.4.0",
|
15
|
+
"eslint": "^3.19.0",
|
16
|
+
"eslint-config-airbnb": "^15.0.1",
|
17
|
+
"eslint-plugin-import": "^2.2.0",
|
18
|
+
"eslint-plugin-jsx-a11y": "^5.0.1",
|
19
|
+
"eslint-plugin-react": "^7.0.1",
|
20
|
+
"jest": "^20.0.1"
|
21
|
+
},
|
22
|
+
"jest": {
|
23
|
+
"modulePathIgnorePatterns": [
|
24
|
+
"package.json"
|
25
|
+
]
|
26
|
+
},
|
27
|
+
"babel": {
|
28
|
+
"presets": [
|
29
|
+
"env"
|
30
|
+
],
|
31
|
+
"plugins": [
|
32
|
+
[
|
33
|
+
"babel-plugin-transform-builtin-extend",
|
34
|
+
{
|
35
|
+
"globals": [
|
36
|
+
"Error"
|
37
|
+
]
|
38
|
+
}
|
39
|
+
]
|
40
|
+
]
|
41
|
+
},
|
42
|
+
"scripts": {
|
43
|
+
"test": "jest --no-cache ./*",
|
44
|
+
"watch": "jest --no-cache --watch ./*",
|
45
|
+
"lint": "eslint .",
|
46
|
+
"lint-test": "eslint . && jest --no-cache ./* "
|
47
|
+
},
|
48
|
+
"eslintConfig": {
|
49
|
+
"parserOptions": {
|
50
|
+
"ecmaVersion": 6,
|
51
|
+
"sourceType": "module"
|
52
|
+
},
|
53
|
+
"env": {
|
54
|
+
"es6": true,
|
55
|
+
"node": true,
|
56
|
+
"jest": true
|
57
|
+
},
|
58
|
+
"extends": "airbnb",
|
59
|
+
"rules": {
|
60
|
+
"import/no-unresolved": "off",
|
61
|
+
"import/extensions": "off"
|
62
|
+
}
|
63
|
+
},
|
64
|
+
"licenses": [
|
65
|
+
"MIT"
|
66
|
+
],
|
67
|
+
"dependencies": {}
|
68
|
+
}
|
69
|
+
|
@@ -5,9 +5,10 @@ function generatePrimes(uptoNumber) {
|
|
5
5
|
return realPrimes;
|
6
6
|
}
|
7
7
|
|
8
|
-
let currentPrime,
|
8
|
+
let currentPrime,
|
9
|
+
possiblePrimes = [];
|
9
10
|
for (let i = 2; i <= uptoNumber; i++) {
|
10
|
-
possiblePrimes.push({ number: i, prime: true});
|
11
|
+
possiblePrimes.push({ number: i, prime: true });
|
11
12
|
}
|
12
13
|
|
13
14
|
for (let i = 2; i < Math.sqrt(possiblePrimes.length); i++) {
|
@@ -38,7 +38,7 @@ const PATTERNS = {
|
|
38
38
|
9: [' _ ',
|
39
39
|
'|_|',
|
40
40
|
' _|',
|
41
|
-
' ']
|
41
|
+
' '],
|
42
42
|
};
|
43
43
|
export default class Parser {
|
44
44
|
convert(text) {
|
@@ -55,7 +55,7 @@ export default class Parser {
|
|
55
55
|
for (let rowNumber = 0; rowNumber < lines.length; rowNumber += 4) {
|
56
56
|
let row = '';
|
57
57
|
for (let rowLine = 0; rowLine < 4; rowLine++) {
|
58
|
-
row += lines[rowNumber + rowLine]
|
58
|
+
row += `${lines[rowNumber + rowLine]}\n`;
|
59
59
|
}
|
60
60
|
rows.push(row.slice(0, -1));
|
61
61
|
}
|
@@ -76,7 +76,7 @@ export default class Parser {
|
|
76
76
|
}
|
77
77
|
|
78
78
|
static getDigit(text) {
|
79
|
-
for (
|
79
|
+
for (const digit in PATTERNS) {
|
80
80
|
if (PATTERNS.hasOwnProperty(digit)) {
|
81
81
|
if (PATTERNS[digit].join('') === text) {
|
82
82
|
return digit;
|
@@ -2,13 +2,12 @@ import Ocr from './ocr-numbers';
|
|
2
2
|
const ocr = new Ocr();
|
3
3
|
|
4
4
|
describe('ocr', () => {
|
5
|
-
|
6
5
|
test('recognizes zero', () => {
|
7
6
|
expect(ocr.convert(
|
8
7
|
' _ \n' +
|
9
8
|
'| |\n' +
|
10
9
|
'|_|\n' +
|
11
|
-
' '
|
10
|
+
' ',
|
12
11
|
)).toBe('0');
|
13
12
|
});
|
14
13
|
|
@@ -17,7 +16,7 @@ describe('ocr', () => {
|
|
17
16
|
' \n' +
|
18
17
|
' |\n' +
|
19
18
|
' |\n' +
|
20
|
-
' '
|
19
|
+
' ',
|
21
20
|
)).toBe('1');
|
22
21
|
});
|
23
22
|
|
@@ -26,7 +25,7 @@ describe('ocr', () => {
|
|
26
25
|
' _ \n' +
|
27
26
|
' _|\n' +
|
28
27
|
'|_ \n' +
|
29
|
-
' '
|
28
|
+
' ',
|
30
29
|
)).toBe('2');
|
31
30
|
});
|
32
31
|
|
@@ -35,7 +34,7 @@ describe('ocr', () => {
|
|
35
34
|
' _ \n' +
|
36
35
|
' _|\n' +
|
37
36
|
' _|\n' +
|
38
|
-
' '
|
37
|
+
' ',
|
39
38
|
)).toBe('3');
|
40
39
|
});
|
41
40
|
|
@@ -44,7 +43,7 @@ describe('ocr', () => {
|
|
44
43
|
' \n' +
|
45
44
|
'|_|\n' +
|
46
45
|
' |\n' +
|
47
|
-
' '
|
46
|
+
' ',
|
48
47
|
)).toBe('4');
|
49
48
|
});
|
50
49
|
|
@@ -53,7 +52,7 @@ describe('ocr', () => {
|
|
53
52
|
' _ \n' +
|
54
53
|
'|_ \n' +
|
55
54
|
' _|\n' +
|
56
|
-
' '
|
55
|
+
' ',
|
57
56
|
)).toBe('5');
|
58
57
|
});
|
59
58
|
|
@@ -62,7 +61,7 @@ describe('ocr', () => {
|
|
62
61
|
' _ \n' +
|
63
62
|
'|_ \n' +
|
64
63
|
'|_|\n' +
|
65
|
-
' '
|
64
|
+
' ',
|
66
65
|
)).toBe('6');
|
67
66
|
});
|
68
67
|
|
@@ -71,7 +70,7 @@ describe('ocr', () => {
|
|
71
70
|
' _ \n' +
|
72
71
|
' |\n' +
|
73
72
|
' |\n' +
|
74
|
-
' '
|
73
|
+
' ',
|
75
74
|
)).toBe('7');
|
76
75
|
});
|
77
76
|
|
@@ -80,7 +79,7 @@ describe('ocr', () => {
|
|
80
79
|
' _ \n' +
|
81
80
|
'|_|\n' +
|
82
81
|
'|_|\n' +
|
83
|
-
' '
|
82
|
+
' ',
|
84
83
|
)).toBe('8');
|
85
84
|
});
|
86
85
|
|
@@ -89,7 +88,7 @@ describe('ocr', () => {
|
|
89
88
|
' _ \n' +
|
90
89
|
'|_|\n' +
|
91
90
|
' _|\n' +
|
92
|
-
' '
|
91
|
+
' ',
|
93
92
|
)).toBe('9');
|
94
93
|
});
|
95
94
|
|
@@ -98,7 +97,7 @@ describe('ocr', () => {
|
|
98
97
|
' _ \n' +
|
99
98
|
' || |\n' +
|
100
99
|
' ||_|\n' +
|
101
|
-
' '
|
100
|
+
' ',
|
102
101
|
)).toBe('10');
|
103
102
|
});
|
104
103
|
|
@@ -107,7 +106,7 @@ describe('ocr', () => {
|
|
107
106
|
' \n' +
|
108
107
|
'| |\n' +
|
109
108
|
'| |\n' +
|
110
|
-
' '
|
109
|
+
' ',
|
111
110
|
)).toBe('?');
|
112
111
|
});
|
113
112
|
|
@@ -116,7 +115,7 @@ describe('ocr', () => {
|
|
116
115
|
' _ _ _ _ \n' +
|
117
116
|
' | || | || | | || || |\n' +
|
118
117
|
' | ||_| ||_| | ||_||_|\n' +
|
119
|
-
' '
|
118
|
+
' ',
|
120
119
|
)).toBe('110101100');
|
121
120
|
});
|
122
121
|
|
@@ -125,7 +124,7 @@ describe('ocr', () => {
|
|
125
124
|
' _ _ _ \n' +
|
126
125
|
' | || | || | || || |\n' +
|
127
126
|
' | | _| ||_| | ||_||_|\n' +
|
128
|
-
' '
|
127
|
+
' ',
|
129
128
|
)).toBe('11?10?1?0');
|
130
129
|
});
|
131
130
|
|
@@ -134,7 +133,7 @@ describe('ocr', () => {
|
|
134
133
|
' _ _ _ _ _ _ _ _ \n' +
|
135
134
|
' | _| _||_||_ |_ ||_||_|| |\n' +
|
136
135
|
' ||_ _| | _||_| ||_| _||_|\n' +
|
137
|
-
' '
|
136
|
+
' ',
|
138
137
|
)).toBe('1234567890');
|
139
138
|
});
|
140
139
|
|
@@ -151,8 +150,7 @@ describe('ocr', () => {
|
|
151
150
|
' _ _ _ \n' +
|
152
151
|
' ||_||_|\n' +
|
153
152
|
' ||_| _|\n' +
|
154
|
-
' '
|
153
|
+
' ',
|
155
154
|
)).toBe('123,456,789');
|
156
155
|
});
|
157
|
-
|
158
156
|
});
|
@@ -1,6 +1,6 @@
|
|
1
1
|
export default function (octal) {
|
2
2
|
octal = octal.match(/[^0-7]/) ? octal = '0' : octal;
|
3
3
|
return {
|
4
|
-
toDecimal: () => octal.split('').reduce((prev, curr) => prev * 8 + parseInt(curr), 0)
|
4
|
+
toDecimal: () => octal.split('').reduce((prev, curr) => prev * 8 + parseInt(curr), 0),
|
5
5
|
};
|
6
6
|
}
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import Octal from './octal';
|
2
2
|
|
3
3
|
describe('octal', () => {
|
4
|
-
|
5
4
|
test('1 is decimal 1', () => {
|
6
5
|
expect(new Octal('1').toDecimal()).toEqual(1);
|
7
6
|
});
|
@@ -41,5 +40,4 @@ describe('octal', () => {
|
|
41
40
|
xtest('considers the digit 8 as invalid', () => {
|
42
41
|
expect(new Octal('12345678').toDecimal()).toEqual(0);
|
43
42
|
});
|
44
|
-
|
45
43
|
});
|
@@ -1,7 +1,11 @@
|
|
1
|
-
|
1
|
+
const isPalindrome = num => num.toString().split('').reverse().join('') === num.toString();
|
2
2
|
|
3
|
-
|
4
|
-
let maxFactor,
|
3
|
+
const Palindromes = (params) => {
|
4
|
+
let maxFactor,
|
5
|
+
minFactor,
|
6
|
+
maxProduct,
|
7
|
+
minProduct,
|
8
|
+
data;
|
5
9
|
maxFactor = params.maxFactor;
|
6
10
|
minFactor = params.minFactor || 1;
|
7
11
|
maxProduct = 1;
|
@@ -10,7 +14,7 @@ let Palindromes = (params) => {
|
|
10
14
|
|
11
15
|
for (let ii = minFactor; ii < maxFactor; ii++) {
|
12
16
|
for (let jj = ii; jj <= maxFactor; jj++) {
|
13
|
-
|
17
|
+
const product = ii * jj;
|
14
18
|
if (isPalindrome(product)) {
|
15
19
|
data[product] = [ii, jj];
|
16
20
|
maxProduct = Math.max(maxProduct, product);
|
@@ -20,17 +24,16 @@ let Palindromes = (params) => {
|
|
20
24
|
}
|
21
25
|
|
22
26
|
return {
|
23
|
-
largest:
|
24
|
-
value:
|
25
|
-
factors: data[maxProduct]
|
27
|
+
largest: {
|
28
|
+
value: maxProduct,
|
29
|
+
factors: data[maxProduct],
|
26
30
|
},
|
27
31
|
smallest: {
|
28
|
-
value:
|
29
|
-
factors: data[minProduct]
|
30
|
-
}
|
32
|
+
value: minProduct,
|
33
|
+
factors: data[minProduct],
|
34
|
+
},
|
31
35
|
};
|
32
36
|
};
|
33
37
|
|
34
38
|
export default Palindromes;
|
35
39
|
|
36
|
-
|
@@ -1,17 +1,16 @@
|
|
1
1
|
import generate from './palindrome-products';
|
2
2
|
|
3
|
-
describe(
|
4
|
-
|
5
|
-
|
6
|
-
const palindromes = generate({maxFactor: 9});
|
3
|
+
describe('Palindrome', () => {
|
4
|
+
test('largest palindrome from single digit factors', () => {
|
5
|
+
const palindromes = generate({ maxFactor: 9 });
|
7
6
|
const largest = palindromes.largest;
|
8
7
|
|
9
8
|
expect(largest.value).toEqual(9);
|
10
|
-
const containsMatch = [[3,3], [1,9]].filter(el => numericalArraysMatch(el, [3,3])).length > 0;
|
9
|
+
const containsMatch = [[3, 3], [1, 9]].filter(el => numericalArraysMatch(el, [3, 3])).length > 0;
|
11
10
|
expect(containsMatch).toBe(true);
|
12
11
|
});
|
13
12
|
|
14
|
-
xtest(
|
13
|
+
xtest('largest palindrome from double digit factors', () => {
|
15
14
|
const palindromes = generate({ maxFactor: 99, minFactor: 10 });
|
16
15
|
const largest = palindromes.largest;
|
17
16
|
|
@@ -19,7 +18,7 @@ describe("Palindrome", function() {
|
|
19
18
|
expect(largest.factors).toEqual([91, 99]);
|
20
19
|
});
|
21
20
|
|
22
|
-
xtest(
|
21
|
+
xtest('smallest palindrome from double digit factors', () => {
|
23
22
|
const palindromes = generate({ maxFactor: 99, minFactor: 10 });
|
24
23
|
const smallest = palindromes.smallest;
|
25
24
|
|
@@ -27,7 +26,7 @@ describe("Palindrome", function() {
|
|
27
26
|
expect(smallest.factors).toEqual([11, 11]);
|
28
27
|
});
|
29
28
|
|
30
|
-
xtest(
|
29
|
+
xtest('largest palindrome from triple digit factors', () => {
|
31
30
|
const palindromes = generate({ maxFactor: 999, minFactor: 100 });
|
32
31
|
const largest = palindromes.largest;
|
33
32
|
|
@@ -35,37 +34,35 @@ describe("Palindrome", function() {
|
|
35
34
|
expect(largest.factors).toEqual([913, 993]);
|
36
35
|
});
|
37
36
|
|
38
|
-
xtest(
|
37
|
+
xtest('smallest palindrome from triple digit factors', () => {
|
39
38
|
const palindromes = generate({ maxFactor: 999, minFactor: 100 });
|
40
39
|
const smallest = palindromes.smallest;
|
41
40
|
|
42
41
|
expect(smallest.value).toEqual(10201);
|
43
42
|
expect(smallest.factors).toEqual([101, 101]);
|
44
43
|
});
|
45
|
-
|
46
44
|
});
|
47
45
|
|
48
|
-
function numericalArraysMatch(a, b){
|
46
|
+
function numericalArraysMatch(a, b) {
|
49
47
|
if (a.length !== b.length) {
|
50
48
|
return false;
|
51
49
|
}
|
52
|
-
|
53
|
-
|
50
|
+
const one = [...a].sort(numericalSort);
|
51
|
+
const two = [...b].sort(numericalSort);
|
54
52
|
let result = true;
|
55
53
|
let index = 0;
|
56
|
-
while (index < one.length){
|
54
|
+
while (index < one.length) {
|
57
55
|
result = result && one[index] === two[index];
|
58
56
|
index++;
|
59
57
|
}
|
60
58
|
return result;
|
61
|
-
|
62
59
|
}
|
63
60
|
|
64
|
-
function numericalSort(x, y){
|
65
|
-
if (x < y){
|
61
|
+
function numericalSort(x, y) {
|
62
|
+
if (x < y) {
|
66
63
|
return -1;
|
67
64
|
}
|
68
|
-
if (x > y){
|
65
|
+
if (x > y) {
|
69
66
|
return 1;
|
70
67
|
}
|
71
68
|
return 0;
|
@@ -1,15 +1,16 @@
|
|
1
1
|
const notAlpha = /[^a-z]+/gi,
|
2
|
-
|
3
|
-
let cleaned,
|
2
|
+
alphaLength = 26;
|
3
|
+
let cleaned,
|
4
|
+
sortedSet;
|
4
5
|
|
5
6
|
class Pangram {
|
6
7
|
|
7
|
-
constructor
|
8
|
-
cleaned = (candidate.replace(notAlpha,'')).toLowerCase();
|
8
|
+
constructor(candidate) {
|
9
|
+
cleaned = (candidate.replace(notAlpha, '')).toLowerCase();
|
9
10
|
sortedSet = new Set([...cleaned].sort());
|
10
11
|
}
|
11
12
|
|
12
|
-
isPangram
|
13
|
+
isPangram() {
|
13
14
|
return sortedSet.size === alphaLength;
|
14
15
|
}
|
15
16
|
}
|