trackler 2.2.1.130 → 2.2.1.131
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/exercises/crypto-square/description.md +4 -5
- data/problem-specifications/exercises/isbn-verifier/canonical-data.json +9 -1
- data/problem-specifications/exercises/kindergarten-garden/canonical-data.json +1 -4
- data/tracks/csharp/build.ps1 +46 -130
- data/tracks/csharp/build.sh +21 -70
- data/tracks/ecmascript/exercises/simple-cipher/simple-cipher.spec.js +14 -0
- data/tracks/fsharp/build.ps1 +46 -130
- data/tracks/fsharp/build.sh +21 -70
- data/tracks/fsharp/exercises/bank-account/BankAccountTest.fs +13 -12
- data/tracks/fsharp/exercises/bank-account/Example.fs +2 -2
- data/tracks/fsharp/exercises/grade-school/.meta/hints.md +1 -0
- data/tracks/fsharp/exercises/grade-school/GradeSchool.fs +6 -4
- data/tracks/fsharp/exercises/zipper/ZipperTest.fs +79 -26
- data/tracks/fsharp/generators/Common.fs +2 -0
- data/tracks/fsharp/generators/Generators.fs +100 -0
- data/tracks/java/exercises/house/.meta/src/reference/java/House.java +2 -2
- data/tracks/java/exercises/house/.meta/version +1 -1
- data/tracks/java/exercises/house/src/test/java/HouseTest.java +157 -172
- data/tracks/java/exercises/rectangles/.meta/version +1 -1
- data/tracks/java/exercises/rectangles/src/test/java/RectangleCounterTest.java +9 -1
- data/tracks/javascript/exercises/bob/bob.spec.js +1 -1
- data/tracks/javascript/exercises/bob/example.js +3 -0
- data/tracks/javascript/exercises/simple-cipher/simple-cipher.spec.js +14 -0
- data/tracks/julia/config.json +2 -2
- data/tracks/julia/exercises/nucleotide-count/example.jl +1 -1
- data/tracks/julia/exercises/nucleotide-count/runtests.jl +1 -1
- data/tracks/perl5/.travis.yml +1 -4
- data/tracks/perl5/exercises/food-chain/.meta/solutions/FoodChainSong.pm +1 -0
- data/tracks/perl5/exercises/pascals-triangle/.meta/solutions/Triangle.pm +1 -0
- data/tracks/perl5/exercises/pig-latin/.meta/solutions/PigLatin.pm +1 -0
- data/tracks/perl5/exercises/robot-simulator/.meta/solutions/Robot.pm +1 -0
- data/tracks/python/config.json +15 -0
- data/tracks/python/exercises/bowling/bowling_test.py +1 -1
- data/tracks/python/exercises/bracket-push/bracket_push_test.py +4 -1
- data/tracks/python/exercises/isbn-verifier/isbn_verifier_test.py +5 -2
- data/tracks/python/exercises/yacht/README.md +85 -0
- data/tracks/python/exercises/yacht/example.py +65 -0
- data/tracks/python/exercises/yacht/yacht.py +18 -0
- data/tracks/python/exercises/yacht/yacht_test.py +90 -0
- data/tracks/typescript/config.json +25 -0
- data/tracks/typescript/exercises/complex-numbers/README.md +64 -0
- data/tracks/typescript/exercises/complex-numbers/complex-numbers.example.ts +45 -0
- data/tracks/typescript/exercises/complex-numbers/complex-numbers.test.ts +216 -0
- data/tracks/typescript/exercises/complex-numbers/complex-numbers.ts +0 -0
- data/tracks/typescript/exercises/complex-numbers/package.json +36 -0
- data/tracks/typescript/exercises/complex-numbers/tsconfig.json +22 -0
- data/tracks/typescript/exercises/complex-numbers/tslint.json +127 -0
- data/tracks/typescript/exercises/complex-numbers/yarn.lock +2624 -0
- data/tracks/typescript/exercises/minesweeper/README.md +55 -0
- data/tracks/typescript/exercises/minesweeper/minesweeper.example.ts +58 -0
- data/tracks/typescript/exercises/minesweeper/minesweeper.test.ts +173 -0
- data/tracks/typescript/exercises/minesweeper/minesweeper.ts +0 -0
- data/tracks/typescript/exercises/minesweeper/package.json +36 -0
- data/tracks/typescript/exercises/minesweeper/tsconfig.json +22 -0
- data/tracks/typescript/exercises/minesweeper/tslint.json +127 -0
- data/tracks/typescript/exercises/minesweeper/yarn.lock +2624 -0
- data/tracks/typescript/exercises/simple-cipher/simple-cipher.test.ts +14 -0
- metadata +22 -2
@@ -0,0 +1,55 @@
|
|
1
|
+
# Minesweeper
|
2
|
+
|
3
|
+
Add the numbers to a minesweeper board.
|
4
|
+
|
5
|
+
Minesweeper is a popular game where the user has to find the mines using
|
6
|
+
numeric hints that indicate how many mines are directly adjacent
|
7
|
+
(horizontally, vertically, diagonally) to a square.
|
8
|
+
|
9
|
+
In this exercise you have to create some code that counts the number of
|
10
|
+
mines adjacent to a square and transforms boards like this (where `*`
|
11
|
+
indicates a mine):
|
12
|
+
|
13
|
+
+-----+
|
14
|
+
| * * |
|
15
|
+
| * |
|
16
|
+
| * |
|
17
|
+
| |
|
18
|
+
+-----+
|
19
|
+
|
20
|
+
into this:
|
21
|
+
|
22
|
+
+-----+
|
23
|
+
|1*3*1|
|
24
|
+
|13*31|
|
25
|
+
| 2*2 |
|
26
|
+
| 111 |
|
27
|
+
+-----+
|
28
|
+
|
29
|
+
## Setup
|
30
|
+
|
31
|
+
Go through the setup instructions for TypeScript to
|
32
|
+
install the necessary dependencies:
|
33
|
+
|
34
|
+
http://exercism.io/languages/typescript
|
35
|
+
|
36
|
+
## Requirements
|
37
|
+
|
38
|
+
Install assignment dependencies:
|
39
|
+
|
40
|
+
```bash
|
41
|
+
$ yarn install
|
42
|
+
```
|
43
|
+
|
44
|
+
## Making the test suite pass
|
45
|
+
|
46
|
+
Execute the tests with:
|
47
|
+
|
48
|
+
```bash
|
49
|
+
$ yarn test
|
50
|
+
```
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
## Submitting Incomplete Solutions
|
55
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
@@ -0,0 +1,58 @@
|
|
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: string[]) {
|
16
|
+
if (noDataPresent(rows)) {
|
17
|
+
return rows
|
18
|
+
}
|
19
|
+
|
20
|
+
const inputBoard = rows.map((row) => [...row])
|
21
|
+
|
22
|
+
const result = inputBoard.map((row, x) => [...row].map((cell, y) => cellToMineOrCount(cell, inputBoard, x, y)))
|
23
|
+
|
24
|
+
return stringify(result as string[][])
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
function cellToMineOrCount(cell: string, inputBoard: string[][], x: number, y: number) {
|
29
|
+
if (cell === MINE) {
|
30
|
+
return MINE
|
31
|
+
}
|
32
|
+
return countAdjacentMines(inputBoard, x, y) || " "
|
33
|
+
}
|
34
|
+
|
35
|
+
function countAdjacentMines(board: string[][], x: number, y: number) {
|
36
|
+
return DELTAS
|
37
|
+
.filter((d) => adjacentSquareIsOnBoard(board, x, d))
|
38
|
+
.filter((d) => adjacentSquareHasMine(board, x, y, d))
|
39
|
+
.length
|
40
|
+
}
|
41
|
+
|
42
|
+
function stringify(board: string[][]) {
|
43
|
+
return board.map((row) => row.join(''))
|
44
|
+
}
|
45
|
+
|
46
|
+
function noDataPresent(rows: string[]) {
|
47
|
+
return rows.length === 0 || rows[0].length === 0
|
48
|
+
}
|
49
|
+
|
50
|
+
function adjacentSquareIsOnBoard(board: string[][], x: number, d: number[]) {
|
51
|
+
return board[x + d[0]]
|
52
|
+
}
|
53
|
+
|
54
|
+
function adjacentSquareHasMine(board: string[][], x: number, y: number, d: number[]) {
|
55
|
+
return board[x + d[0]][y + d[1]] === MINE
|
56
|
+
}
|
57
|
+
|
58
|
+
export default Minesweeper
|
@@ -0,0 +1,173 @@
|
|
1
|
+
import Minesweeper from './minesweeper'
|
2
|
+
|
3
|
+
describe('Minesweeper()', () => {
|
4
|
+
let minesweeper: Minesweeper
|
5
|
+
|
6
|
+
beforeEach(() => {
|
7
|
+
minesweeper = new Minesweeper()
|
8
|
+
})
|
9
|
+
|
10
|
+
it('handles no rows', () => {
|
11
|
+
expect(minesweeper.annotate([])).toEqual([])
|
12
|
+
})
|
13
|
+
|
14
|
+
xit('handles no columns', () => {
|
15
|
+
expect(minesweeper.annotate([''])).toEqual([''])
|
16
|
+
})
|
17
|
+
|
18
|
+
xit('handles no mines', () => {
|
19
|
+
const input = [
|
20
|
+
' ',
|
21
|
+
' ',
|
22
|
+
' ',
|
23
|
+
]
|
24
|
+
const expected = [
|
25
|
+
' ',
|
26
|
+
' ',
|
27
|
+
' ',
|
28
|
+
]
|
29
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
30
|
+
})
|
31
|
+
|
32
|
+
xit('handles board with only mines', () => {
|
33
|
+
const input = [
|
34
|
+
'***',
|
35
|
+
'***',
|
36
|
+
'***',
|
37
|
+
]
|
38
|
+
const expected = [
|
39
|
+
'***',
|
40
|
+
'***',
|
41
|
+
'***',
|
42
|
+
]
|
43
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
44
|
+
})
|
45
|
+
|
46
|
+
xit('handles mine surrounded by spaces', () => {
|
47
|
+
const input = [
|
48
|
+
' ',
|
49
|
+
' * ',
|
50
|
+
' ',
|
51
|
+
]
|
52
|
+
const expected = [
|
53
|
+
'111',
|
54
|
+
'1*1',
|
55
|
+
'111',
|
56
|
+
]
|
57
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
58
|
+
})
|
59
|
+
|
60
|
+
xit('handles space surrounded by mines', () => {
|
61
|
+
const input = [
|
62
|
+
'***',
|
63
|
+
'* *',
|
64
|
+
'***',
|
65
|
+
]
|
66
|
+
const expected = [
|
67
|
+
'***',
|
68
|
+
'*8*',
|
69
|
+
'***',
|
70
|
+
]
|
71
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
72
|
+
})
|
73
|
+
|
74
|
+
xit('handles space surrounded by mines', () => {
|
75
|
+
const input = [
|
76
|
+
'***',
|
77
|
+
'* *',
|
78
|
+
'***',
|
79
|
+
]
|
80
|
+
const expected = [
|
81
|
+
'***',
|
82
|
+
'*8*',
|
83
|
+
'***',
|
84
|
+
]
|
85
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
86
|
+
})
|
87
|
+
|
88
|
+
xit('handles horizontal line', () => {
|
89
|
+
const input = [' * * ']
|
90
|
+
const expected = ['1*2*1']
|
91
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
92
|
+
})
|
93
|
+
|
94
|
+
xit('handles horizontal line, mines at edges', () => {
|
95
|
+
const input = ['* *']
|
96
|
+
const expected = ['*1 1*']
|
97
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
98
|
+
})
|
99
|
+
|
100
|
+
xit('handles vertical line', () => {
|
101
|
+
const input = [
|
102
|
+
' ',
|
103
|
+
'*',
|
104
|
+
' ',
|
105
|
+
'*',
|
106
|
+
' ',
|
107
|
+
]
|
108
|
+
const expected = [
|
109
|
+
'1',
|
110
|
+
'*',
|
111
|
+
'2',
|
112
|
+
'*',
|
113
|
+
'1',
|
114
|
+
]
|
115
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
116
|
+
})
|
117
|
+
|
118
|
+
xit('handles vertical line, mines at edges', () => {
|
119
|
+
const input = [
|
120
|
+
'*',
|
121
|
+
' ',
|
122
|
+
' ',
|
123
|
+
' ',
|
124
|
+
'*',
|
125
|
+
]
|
126
|
+
const expected = [
|
127
|
+
'*',
|
128
|
+
'1',
|
129
|
+
' ',
|
130
|
+
'1',
|
131
|
+
'*',
|
132
|
+
]
|
133
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
134
|
+
})
|
135
|
+
|
136
|
+
xit('handles cross', () => {
|
137
|
+
const input = [
|
138
|
+
' * ',
|
139
|
+
' * ',
|
140
|
+
'*****',
|
141
|
+
' * ',
|
142
|
+
' * ',
|
143
|
+
]
|
144
|
+
const expected = [
|
145
|
+
' 2*2 ',
|
146
|
+
'25*52',
|
147
|
+
'*****',
|
148
|
+
'25*52',
|
149
|
+
' 2*2 ',
|
150
|
+
]
|
151
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
152
|
+
})
|
153
|
+
|
154
|
+
xit('handles large board', () => {
|
155
|
+
const input = [
|
156
|
+
' * * ',
|
157
|
+
' * ',
|
158
|
+
' * ',
|
159
|
+
' * *',
|
160
|
+
' * * ',
|
161
|
+
' ',
|
162
|
+
]
|
163
|
+
const expected = [
|
164
|
+
'1*22*1',
|
165
|
+
'12*322',
|
166
|
+
' 123*2',
|
167
|
+
'112*4*',
|
168
|
+
'1*22*2',
|
169
|
+
'111111',
|
170
|
+
]
|
171
|
+
expect(minesweeper.annotate(input)).toEqual(expected)
|
172
|
+
})
|
173
|
+
})
|
File without changes
|
@@ -0,0 +1,36 @@
|
|
1
|
+
{
|
2
|
+
"name": "xtypescript",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "Exercism exercises in Typescript.",
|
5
|
+
"author": "",
|
6
|
+
"private": true,
|
7
|
+
"repository": {
|
8
|
+
"type": "git",
|
9
|
+
"url": "https://github.com/exercism/xtypescript"
|
10
|
+
},
|
11
|
+
"devDependencies": {},
|
12
|
+
"scripts": {
|
13
|
+
"test": "tsc --noEmit -p . && jest --no-cache",
|
14
|
+
"lint": "tsc --noEmit -p . && tslint \"*.ts?(x)\"",
|
15
|
+
"lintci": "tslint \"*.ts?(x)\" --force"
|
16
|
+
},
|
17
|
+
"dependencies": {
|
18
|
+
"@types/jest": "^21.1.5",
|
19
|
+
"@types/node": "^8.0.47",
|
20
|
+
"jest": "^21.2.1",
|
21
|
+
"ts-jest": "^21.1.3",
|
22
|
+
"tslint": "^5.8.0",
|
23
|
+
"typescript": "^2.5.3"
|
24
|
+
},
|
25
|
+
"jest": {
|
26
|
+
"transform": {
|
27
|
+
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
|
28
|
+
},
|
29
|
+
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
|
30
|
+
"moduleFileExtensions": [
|
31
|
+
"ts",
|
32
|
+
"tsx",
|
33
|
+
"js"
|
34
|
+
]
|
35
|
+
}
|
36
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"target": "es2017",
|
4
|
+
"module": "commonjs",
|
5
|
+
"alwaysStrict": true,
|
6
|
+
"noUnusedLocals": true,
|
7
|
+
"noUnusedParameters": true,
|
8
|
+
"noImplicitAny": true,
|
9
|
+
"strictNullChecks": true,
|
10
|
+
"preserveConstEnums": true,
|
11
|
+
"noFallthroughCasesInSwitch":true,
|
12
|
+
"noImplicitThis":true,
|
13
|
+
"noImplicitReturns":true,
|
14
|
+
"sourceMap": true,
|
15
|
+
"noEmitOnError": true,
|
16
|
+
"outDir": "./build"
|
17
|
+
},
|
18
|
+
"compileOnSave": true,
|
19
|
+
"exclude": [
|
20
|
+
"node_modules"
|
21
|
+
]
|
22
|
+
}
|
@@ -0,0 +1,127 @@
|
|
1
|
+
{
|
2
|
+
"jsRules": {
|
3
|
+
"class-name": true,
|
4
|
+
"comment-format": [
|
5
|
+
true,
|
6
|
+
"check-space"
|
7
|
+
],
|
8
|
+
"indent": [
|
9
|
+
true,
|
10
|
+
"spaces"
|
11
|
+
],
|
12
|
+
"no-duplicate-variable": true,
|
13
|
+
"no-eval": true,
|
14
|
+
"no-trailing-whitespace": true,
|
15
|
+
"no-unsafe-finally": true,
|
16
|
+
"one-line": [
|
17
|
+
true,
|
18
|
+
"check-open-brace",
|
19
|
+
"check-whitespace"
|
20
|
+
],
|
21
|
+
"quotemark": [
|
22
|
+
false,
|
23
|
+
"double"
|
24
|
+
],
|
25
|
+
"semicolon": [
|
26
|
+
true,
|
27
|
+
"never"
|
28
|
+
],
|
29
|
+
"triple-equals": [
|
30
|
+
true,
|
31
|
+
"allow-null-check"
|
32
|
+
],
|
33
|
+
"variable-name": [
|
34
|
+
true,
|
35
|
+
"ban-keywords"
|
36
|
+
],
|
37
|
+
"whitespace": [
|
38
|
+
true,
|
39
|
+
"check-branch",
|
40
|
+
"check-decl",
|
41
|
+
"check-operator",
|
42
|
+
"check-separator",
|
43
|
+
"check-type"
|
44
|
+
]
|
45
|
+
},
|
46
|
+
"rules": {
|
47
|
+
"class-name": true,
|
48
|
+
"comment-format": [
|
49
|
+
true,
|
50
|
+
"check-space"
|
51
|
+
],
|
52
|
+
"indent": [
|
53
|
+
true,
|
54
|
+
"spaces"
|
55
|
+
],
|
56
|
+
"no-eval": true,
|
57
|
+
"no-internal-module": true,
|
58
|
+
"no-trailing-whitespace": true,
|
59
|
+
"no-unsafe-finally": true,
|
60
|
+
"no-var-keyword": true,
|
61
|
+
"one-line": [
|
62
|
+
true,
|
63
|
+
"check-open-brace",
|
64
|
+
"check-whitespace"
|
65
|
+
],
|
66
|
+
"semicolon": [
|
67
|
+
true,
|
68
|
+
"never"
|
69
|
+
],
|
70
|
+
"triple-equals": [
|
71
|
+
true,
|
72
|
+
"allow-null-check"
|
73
|
+
],
|
74
|
+
"typedef-whitespace": [
|
75
|
+
true,
|
76
|
+
{
|
77
|
+
"call-signature": "nospace",
|
78
|
+
"index-signature": "nospace",
|
79
|
+
"parameter": "nospace",
|
80
|
+
"property-declaration": "nospace",
|
81
|
+
"variable-declaration": "nospace"
|
82
|
+
}
|
83
|
+
],
|
84
|
+
"variable-name": [
|
85
|
+
true,
|
86
|
+
"ban-keywords"
|
87
|
+
],
|
88
|
+
"whitespace": [
|
89
|
+
true,
|
90
|
+
"check-branch",
|
91
|
+
"check-decl",
|
92
|
+
"check-operator",
|
93
|
+
"check-separator",
|
94
|
+
"check-type"
|
95
|
+
],
|
96
|
+
"no-namespace": true,
|
97
|
+
"prefer-for-of": true,
|
98
|
+
"only-arrow-functions": [true, "allow-declarations"],
|
99
|
+
"no-var-requires": true,
|
100
|
+
"no-any": true,
|
101
|
+
"curly": true,
|
102
|
+
"forin": true,
|
103
|
+
"no-arg": true,
|
104
|
+
"label-position": true,
|
105
|
+
"no-conditional-assignment": true,
|
106
|
+
"no-console": [true, "log", "error"],
|
107
|
+
"no-construct": true,
|
108
|
+
"no-duplicate-variable": true,
|
109
|
+
"no-empty": true,
|
110
|
+
"no-invalid-this": [true, "check-function-in-method"],
|
111
|
+
"no-misused-new": true,
|
112
|
+
"no-null-keyword": true,
|
113
|
+
"no-string-literal": true,
|
114
|
+
"radix": true,
|
115
|
+
"typeof-compare": true,
|
116
|
+
"use-isnan": true,
|
117
|
+
"prefer-const": true,
|
118
|
+
"array-type": [true, "array-simple"],
|
119
|
+
"arrow-parens": true,
|
120
|
+
"new-parens": true,
|
121
|
+
"no-consecutive-blank-lines": [true,1],
|
122
|
+
"no-parameter-properties": true,
|
123
|
+
"no-unnecessary-initializer": true,
|
124
|
+
"object-literal-shorthand": true,
|
125
|
+
"object-literal-key-quotes": [true, "as-needed"]
|
126
|
+
}
|
127
|
+
}
|