trackler 2.0.3.3 → 2.0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/haskell/exercises/pov/.dummylink +1 -0
- data/tracks/haskell/exercises/pov/stack.yaml +1 -0
- data/tracks/ocaml/config.json +4 -1
- data/tracks/ocaml/exercises/difference-of-squares/test.ml +31 -23
- data/tracks/ocaml/exercises/minesweeper/test.ml +104 -30
- data/tracks/ocaml/tools/test-generator/templates/minesweeper/template.ml +28 -0
- data/tracks/php/config.json +138 -34
- data/tracks/php/exercises/robot-name/example.php +54 -15
- data/tracks/php/exercises/robot-name/robot-name_test.php +23 -0
- data/tracks/scala/exercises/gigasecond/HINTS.md +3 -0
- data/tracks/scala/exercises/roman-numerals/HINTS.md +10 -0
- data/tracks/swift/config.json +8 -0
- data/tracks/swift/exercises/transpose/TransposeExample.swift +35 -0
- data/tracks/swift/exercises/transpose/TransposeTest.swift +135 -0
- data/tracks/swift/xcodeProject/xSwift.xcodeproj/project.pbxproj +17 -0
- metadata +8 -2
- data/tracks/haskell/exercises/pov/stack.yaml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36080e740c50fc72852fc37ec458b86bfbfc9e44
|
4
|
+
data.tar.gz: a5c5c21f888bc1a2c926b81bfa7cf0c3b529558a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54197c20523de15b52d62db122611be7b844ce329283a3d2bb59840899a7545bed21c0f44e6e2c094765b546d46ee4f95a311941cc23a4761d1f87f50fbce44d
|
7
|
+
data.tar.gz: 1e14225a99cab48c3125db478b9d50440aad4109efbdb88a5fd77cc383c29bfc9cdcb9295d6920ea7772d9e56a1f1f0eec8dc774ff8168c8d0d09a0ddd2821e9
|
data/lib/trackler/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
tracks/haskell/exercises/pov/../../common/stack.yaml
|
@@ -0,0 +1 @@
|
|
1
|
+
resolver: lts-7.9
|
data/tracks/ocaml/config.json
CHANGED
@@ -4,29 +4,37 @@ open Difference_of_squares
|
|
4
4
|
|
5
5
|
let ae exp got _test_ctxt = assert_equal exp got
|
6
6
|
|
7
|
-
let
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
7
|
+
let square_of_sum_tests = [
|
8
|
+
"square of sum 5" >::
|
9
|
+
ae 225 (square_of_sum 5);
|
10
|
+
"square of sum 10" >::
|
11
|
+
ae 3025 (square_of_sum 10);
|
12
|
+
"square of sum 100" >::
|
13
|
+
ae 25502500 (square_of_sum 100);
|
14
|
+
]
|
15
|
+
|
16
|
+
let sum_of_squares_tests = [
|
17
|
+
"sum of squares 5" >::
|
18
|
+
ae 55 (sum_of_squares 5);
|
19
|
+
"sum of squares 10" >::
|
20
|
+
ae 385 (sum_of_squares 10);
|
21
|
+
"sum of squares 100" >::
|
22
|
+
ae 338350 (sum_of_squares 100);
|
23
|
+
]
|
24
|
+
|
25
|
+
let difference_of_squares_tests = [
|
26
|
+
"difference of squares 0" >::
|
27
|
+
ae 0 (difference_of_squares 0);
|
28
|
+
"difference of squares 5" >::
|
29
|
+
ae 170 (difference_of_squares 5);
|
30
|
+
"difference of squares 10" >::
|
31
|
+
ae 2640 (difference_of_squares 10);
|
32
|
+
"difference of squares 100" >::
|
33
|
+
ae 25164150 (difference_of_squares 100);
|
29
34
|
]
|
30
35
|
|
31
36
|
let () =
|
32
|
-
run_test_tt_main (
|
37
|
+
run_test_tt_main (
|
38
|
+
"difference of squares tests" >:::
|
39
|
+
List.concat [square_of_sum_tests; sum_of_squares_tests; difference_of_squares_tests]
|
40
|
+
)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
open Core.Std
|
2
2
|
open OUnit2
|
3
|
+
open Minesweeper
|
3
4
|
|
4
5
|
let format_board strings =
|
5
6
|
let width = match strings with
|
@@ -13,45 +14,118 @@ let format_board strings =
|
|
13
14
|
let ae exp got =
|
14
15
|
assert_equal exp got ~cmp:(List.equal ~equal:String.equal) ~printer:format_board
|
15
16
|
|
16
|
-
let
|
17
|
-
|
18
|
-
|
19
|
-
let
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
let tests = [
|
18
|
+
"no rows" >:: (fun _ ->
|
19
|
+
let b = [] in
|
20
|
+
let expected = [] in
|
21
|
+
ae expected (annotate b)
|
22
|
+
);
|
23
|
+
"no columns" >:: (fun _ ->
|
24
|
+
let b = [""] in
|
25
|
+
let expected = [""] in
|
26
|
+
ae expected (annotate b)
|
27
|
+
);
|
28
|
+
"no mines" >:: (fun _ ->
|
23
29
|
let b = [" ";
|
24
30
|
" ";
|
25
31
|
" "] in
|
26
|
-
|
27
|
-
"
|
32
|
+
let expected = [" ";
|
33
|
+
" ";
|
34
|
+
" "] in
|
35
|
+
ae expected (annotate b)
|
36
|
+
);
|
37
|
+
"board with only mines" >:: (fun _ ->
|
28
38
|
let b = ["***";
|
29
39
|
"***";
|
30
40
|
"***"] in
|
31
|
-
|
32
|
-
|
41
|
+
let expected = ["***";
|
42
|
+
"***";
|
43
|
+
"***"] in
|
44
|
+
ae expected (annotate b)
|
45
|
+
);
|
46
|
+
"mine surrounded by spaces" >:: (fun _ ->
|
47
|
+
let b = [" ";
|
48
|
+
" * ";
|
49
|
+
" "] in
|
50
|
+
let expected = ["111";
|
51
|
+
"1*1";
|
52
|
+
"111"] in
|
53
|
+
ae expected (annotate b)
|
54
|
+
);
|
55
|
+
"space surrounded by mines" >:: (fun _ ->
|
33
56
|
let b = ["***";
|
34
|
-
"*
|
57
|
+
"* *";
|
35
58
|
"***"] in
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
ae
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
"
|
48
|
-
let
|
49
|
-
|
59
|
+
let expected = ["***";
|
60
|
+
"*8*";
|
61
|
+
"***"] in
|
62
|
+
ae expected (annotate b)
|
63
|
+
);
|
64
|
+
"horizontal line" >:: (fun _ ->
|
65
|
+
let b = [" * * "] in
|
66
|
+
let expected = ["1*2*1"] in
|
67
|
+
ae expected (annotate b)
|
68
|
+
);
|
69
|
+
"horizontal line, mines at edges" >:: (fun _ ->
|
70
|
+
let b = ["* *"] in
|
71
|
+
let expected = ["*1 1*"] in
|
72
|
+
ae expected (annotate b)
|
73
|
+
);
|
74
|
+
"vertical line" >:: (fun _ ->
|
75
|
+
let b = [" ";
|
76
|
+
"*";
|
77
|
+
" ";
|
78
|
+
"*";
|
79
|
+
" "] in
|
80
|
+
let expected = ["1";
|
81
|
+
"*";
|
82
|
+
"2";
|
83
|
+
"*";
|
84
|
+
"1"] in
|
85
|
+
ae expected (annotate b)
|
86
|
+
);
|
87
|
+
"vertical line, mines at edges" >:: (fun _ ->
|
88
|
+
let b = ["*";
|
89
|
+
" ";
|
90
|
+
" ";
|
91
|
+
" ";
|
92
|
+
"*"] in
|
93
|
+
let expected = ["*";
|
94
|
+
"1";
|
95
|
+
" ";
|
96
|
+
"1";
|
97
|
+
"*"] in
|
98
|
+
ae expected (annotate b)
|
99
|
+
);
|
100
|
+
"cross" >:: (fun _ ->
|
101
|
+
let b = [" * ";
|
102
|
+
" * ";
|
50
103
|
"*****";
|
51
|
-
"
|
52
|
-
"
|
53
|
-
|
54
|
-
|
104
|
+
" * ";
|
105
|
+
" * "] in
|
106
|
+
let expected = [" 2*2 ";
|
107
|
+
"25*52";
|
108
|
+
"*****";
|
109
|
+
"25*52";
|
110
|
+
" 2*2 "] in
|
111
|
+
ae expected (annotate b)
|
112
|
+
);
|
113
|
+
"large board" >:: (fun _ ->
|
114
|
+
let b = [" * * ";
|
115
|
+
" * ";
|
116
|
+
" * ";
|
117
|
+
" * *";
|
118
|
+
" * * ";
|
119
|
+
" "] in
|
120
|
+
let expected = ["1*22*1";
|
121
|
+
"12*322";
|
122
|
+
" 123*2";
|
123
|
+
"112*4*";
|
124
|
+
"1*22*2";
|
125
|
+
"111111"] in
|
126
|
+
ae expected (annotate b)
|
127
|
+
);
|
128
|
+
]
|
55
129
|
|
56
130
|
let () =
|
57
131
|
run_test_tt_main ("minesweeper tests" >::: tests)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
open Core.Std
|
2
|
+
open OUnit2
|
3
|
+
open Minesweeper
|
4
|
+
|
5
|
+
let format_board strings =
|
6
|
+
let width = match strings with
|
7
|
+
| [] -> 0
|
8
|
+
| (s::_) -> String.length s in
|
9
|
+
let border_line = "+" ^ String.make width '-' ^ "+\n" in
|
10
|
+
let line s = "|" ^ s ^ "|\n" in
|
11
|
+
"\n" ^ border_line ^ String.concat (List.map strings ~f:line) ^ border_line
|
12
|
+
|
13
|
+
(* Assert Equals *)
|
14
|
+
let ae exp got =
|
15
|
+
assert_equal exp got ~cmp:(List.equal ~equal:String.equal) ~printer:format_board
|
16
|
+
|
17
|
+
let tests = [
|
18
|
+
(* TEST
|
19
|
+
"$description" >:: (fun _ ->
|
20
|
+
let b = $input in
|
21
|
+
let expected = $expected in
|
22
|
+
ae expected (annotate b)
|
23
|
+
);
|
24
|
+
END TEST *)
|
25
|
+
]
|
26
|
+
|
27
|
+
let () =
|
28
|
+
run_test_tt_main ("minesweeper tests" >::: tests)
|
data/tracks/php/config.json
CHANGED
@@ -17,87 +17,137 @@
|
|
17
17
|
{
|
18
18
|
"slug": "hello-world",
|
19
19
|
"difficulty": 1,
|
20
|
-
"topics": [
|
20
|
+
"topics": [
|
21
|
+
"Text formatting",
|
22
|
+
"Optional values"
|
23
|
+
]
|
21
24
|
},
|
22
25
|
{
|
23
26
|
"slug": "hamming",
|
24
27
|
"difficulty": 2,
|
25
|
-
"topics": [
|
28
|
+
"topics": [
|
29
|
+
"Strings",
|
30
|
+
"Filtering"
|
31
|
+
]
|
26
32
|
},
|
27
33
|
{
|
28
34
|
"slug": "gigasecond",
|
29
35
|
"difficulty": 2,
|
30
|
-
"topics": [
|
36
|
+
"topics": [
|
37
|
+
"Dates"
|
38
|
+
]
|
31
39
|
},
|
32
40
|
{
|
33
41
|
"slug": "bob",
|
34
42
|
"difficulty": 4,
|
35
|
-
"topics": [
|
43
|
+
"topics": [
|
44
|
+
"Strings",
|
45
|
+
"Control-flow (if-else statements)"
|
46
|
+
]
|
36
47
|
},
|
37
48
|
{
|
38
49
|
"slug": "pangram",
|
39
50
|
"difficulty": 4,
|
40
|
-
"topics": [
|
51
|
+
"topics": [
|
52
|
+
"Strings"
|
53
|
+
]
|
41
54
|
},
|
42
55
|
{
|
43
56
|
"slug": "rna-transcription",
|
44
57
|
"difficulty": 3,
|
45
|
-
"topics": [
|
58
|
+
"topics": [
|
59
|
+
"Strings",
|
60
|
+
"Transforming"
|
61
|
+
]
|
46
62
|
},
|
47
63
|
{
|
48
64
|
"slug": "raindrops",
|
49
65
|
"difficulty": 6,
|
50
|
-
"topics": [
|
66
|
+
"topics": [
|
67
|
+
"Text formatting",
|
68
|
+
"Filtering"
|
69
|
+
]
|
51
70
|
},
|
52
71
|
{
|
53
72
|
"slug": "isogram",
|
54
73
|
"difficulty": 4,
|
55
|
-
"topics": [
|
74
|
+
"topics": [
|
75
|
+
"Strings",
|
76
|
+
"Filtering"
|
77
|
+
]
|
56
78
|
},
|
57
79
|
{
|
58
80
|
"slug": "difference-of-squares",
|
59
81
|
"difficulty": 2,
|
60
|
-
"topics": [
|
82
|
+
"topics": [
|
83
|
+
"Integers"
|
84
|
+
]
|
61
85
|
},
|
62
86
|
{
|
63
87
|
"slug": "largest-series-product",
|
64
88
|
"difficulty": 5,
|
65
|
-
"topics": [
|
89
|
+
"topics": [
|
90
|
+
"Strings",
|
91
|
+
"Integers",
|
92
|
+
"Transforming"
|
93
|
+
]
|
66
94
|
},
|
67
95
|
{
|
68
96
|
"slug": "roman-numerals",
|
69
97
|
"difficulty": 4,
|
70
|
-
"topics": [
|
98
|
+
"topics": [
|
99
|
+
"Control-flow (loops)",
|
100
|
+
"Transforming"
|
101
|
+
]
|
71
102
|
},
|
72
103
|
{
|
73
104
|
"slug": "sieve",
|
74
105
|
"difficulty": 1,
|
75
|
-
"topics": [
|
106
|
+
"topics": [
|
107
|
+
"Filtering",
|
108
|
+
"Mathematics"
|
109
|
+
]
|
76
110
|
},
|
77
111
|
{
|
78
112
|
"slug": "pig-latin",
|
79
113
|
"difficulty": 4,
|
80
|
-
"topics": [
|
114
|
+
"topics": [
|
115
|
+
"Strings",
|
116
|
+
"Transforming"
|
117
|
+
]
|
81
118
|
},
|
82
119
|
{
|
83
120
|
"slug": "robot-name",
|
84
121
|
"difficulty": 3,
|
85
|
-
"topics": [
|
122
|
+
"topics": [
|
123
|
+
"Randomness",
|
124
|
+
"Strings",
|
125
|
+
"Classes"
|
126
|
+
]
|
86
127
|
},
|
87
128
|
{
|
88
129
|
"slug": "leap",
|
89
130
|
"difficulty": 1,
|
90
|
-
"topics": [
|
131
|
+
"topics": [
|
132
|
+
"Integers"
|
133
|
+
]
|
91
134
|
},
|
92
135
|
{
|
93
136
|
"slug": "word-count",
|
94
137
|
"difficulty": 1,
|
95
|
-
"topics": [
|
138
|
+
"topics": [
|
139
|
+
"Strings",
|
140
|
+
"Dictionaries",
|
141
|
+
"Transforming"
|
142
|
+
]
|
96
143
|
},
|
97
144
|
{
|
98
145
|
"slug": "anagram",
|
99
146
|
"difficulty": 1,
|
100
|
-
"topics": [
|
147
|
+
"topics": [
|
148
|
+
"Strings",
|
149
|
+
"Filtering"
|
150
|
+
]
|
101
151
|
},
|
102
152
|
{
|
103
153
|
"slug": "trinary",
|
@@ -107,17 +157,27 @@
|
|
107
157
|
{
|
108
158
|
"slug": "bowling",
|
109
159
|
"difficulty": 1,
|
110
|
-
"topics": [
|
160
|
+
"topics": [
|
161
|
+
"Algorithms",
|
162
|
+
"Control-flow (loops)"
|
163
|
+
]
|
111
164
|
},
|
112
165
|
{
|
113
166
|
"slug": "clock",
|
114
167
|
"difficulty": 1,
|
115
|
-
"topics": [
|
168
|
+
"topics": [
|
169
|
+
"Time",
|
170
|
+
"Structural equality"
|
171
|
+
]
|
116
172
|
},
|
117
173
|
{
|
118
174
|
"slug": "wordy",
|
119
175
|
"difficulty": 1,
|
120
|
-
"topics": [
|
176
|
+
"topics": [
|
177
|
+
"Parsing",
|
178
|
+
"Strings",
|
179
|
+
"Transforming"
|
180
|
+
]
|
121
181
|
},
|
122
182
|
{
|
123
183
|
"slug": "connect",
|
@@ -127,32 +187,51 @@
|
|
127
187
|
{
|
128
188
|
"slug": "minesweeper",
|
129
189
|
"difficulty": 1,
|
130
|
-
"topics": [
|
190
|
+
"topics": [
|
191
|
+
"Parsing",
|
192
|
+
"Transforming"
|
193
|
+
]
|
131
194
|
},
|
132
195
|
{
|
133
196
|
"slug": "change",
|
134
197
|
"difficulty": 1,
|
135
|
-
"topics": [
|
198
|
+
"topics": [
|
199
|
+
"Integers",
|
200
|
+
"Arrays"
|
201
|
+
]
|
136
202
|
},
|
137
203
|
{
|
138
204
|
"slug": "phone-number",
|
139
205
|
"difficulty": 1,
|
140
|
-
"topics": [
|
206
|
+
"topics": [
|
207
|
+
"Parsing",
|
208
|
+
"Transforming"
|
209
|
+
]
|
141
210
|
},
|
142
211
|
{
|
143
212
|
"slug": "beer-song",
|
144
213
|
"difficulty": 1,
|
145
|
-
"topics": [
|
214
|
+
"topics": [
|
215
|
+
"Text formatting",
|
216
|
+
"Algorithms"
|
217
|
+
]
|
146
218
|
},
|
147
219
|
{
|
148
220
|
"slug": "atbash-cipher",
|
149
221
|
"difficulty": 1,
|
150
|
-
"topics": [
|
222
|
+
"topics": [
|
223
|
+
"Strings",
|
224
|
+
"Algorithms",
|
225
|
+
"Transforming"
|
226
|
+
]
|
151
227
|
},
|
152
228
|
{
|
153
229
|
"slug": "bracket-push",
|
154
230
|
"difficulty": 1,
|
155
|
-
"topics": [
|
231
|
+
"topics": [
|
232
|
+
"Parsing",
|
233
|
+
"Strings"
|
234
|
+
]
|
156
235
|
},
|
157
236
|
{
|
158
237
|
"slug": "binary",
|
@@ -162,42 +241,67 @@
|
|
162
241
|
{
|
163
242
|
"slug": "accumulate",
|
164
243
|
"difficulty": 1,
|
165
|
-
"topics": [
|
244
|
+
"topics": [
|
245
|
+
"Extension methods",
|
246
|
+
"Sequences",
|
247
|
+
"Transforming"
|
248
|
+
]
|
166
249
|
},
|
167
250
|
{
|
168
251
|
"slug": "variable-length-quantity",
|
169
252
|
"difficulty": 1,
|
170
|
-
"topics": [
|
253
|
+
"topics": [
|
254
|
+
"Bitwise operations",
|
255
|
+
"Algorithms"
|
256
|
+
]
|
171
257
|
},
|
172
258
|
{
|
173
259
|
"slug": "acronym",
|
174
260
|
"difficulty": 1,
|
175
|
-
"topics": [
|
261
|
+
"topics": [
|
262
|
+
"Strings",
|
263
|
+
"Transforming"
|
264
|
+
]
|
176
265
|
},
|
177
266
|
{
|
178
267
|
"slug": "nucleotide-count",
|
179
268
|
"difficulty": 1,
|
180
|
-
"topics": [
|
269
|
+
"topics": [
|
270
|
+
"Dictionaries",
|
271
|
+
"Strings"
|
272
|
+
]
|
181
273
|
},
|
182
274
|
{
|
183
275
|
"slug": "triangle",
|
184
276
|
"difficulty": 1,
|
185
|
-
"topics": [
|
277
|
+
"topics": [
|
278
|
+
"Integers",
|
279
|
+
"Enumerations"
|
280
|
+
]
|
186
281
|
},
|
187
282
|
{
|
188
283
|
"slug": "etl",
|
189
284
|
"difficulty": 1,
|
190
|
-
"topics": [
|
285
|
+
"topics": [
|
286
|
+
"Dictionaries",
|
287
|
+
"Lists",
|
288
|
+
"Transforming"
|
289
|
+
]
|
191
290
|
},
|
192
291
|
{
|
193
292
|
"slug": "space-age",
|
194
293
|
"difficulty": 1,
|
195
|
-
"topics": [
|
294
|
+
"topics": [
|
295
|
+
"Floating-point numbers"
|
296
|
+
]
|
196
297
|
},
|
197
298
|
{
|
198
299
|
"slug": "allergies",
|
199
300
|
"difficulty": 3,
|
200
|
-
"topics": [
|
301
|
+
"topics": [
|
302
|
+
"Bitwise operations",
|
303
|
+
"Filtering"
|
304
|
+
]
|
201
305
|
},
|
202
306
|
{
|
203
307
|
"slug": "markdown",
|
@@ -1,37 +1,76 @@
|
|
1
1
|
<?php
|
2
|
-
|
3
2
|
class Robot
|
4
3
|
{
|
5
|
-
|
6
|
-
|
7
|
-
protected $alphabet = '';
|
4
|
+
private $name;
|
8
5
|
|
9
6
|
public function __construct()
|
10
7
|
{
|
11
|
-
$this->
|
8
|
+
$this->reset();
|
12
9
|
}
|
13
10
|
|
11
|
+
/**
|
12
|
+
* Get Robot name
|
13
|
+
*
|
14
|
+
* @return string
|
15
|
+
*/
|
14
16
|
public function getName()
|
15
17
|
{
|
16
|
-
if (is_null($this->name)) {
|
17
|
-
$this->name = sprintf('%s%s', $this->getPrefix(), $this->getSuffix());
|
18
|
-
}
|
19
|
-
|
20
18
|
return $this->name;
|
21
19
|
}
|
22
20
|
|
23
|
-
|
21
|
+
/**
|
22
|
+
* Reset name
|
23
|
+
*/
|
24
|
+
public function reset()
|
25
|
+
{
|
26
|
+
$this->name = NamesRegistry::connect()->getNewName();
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
class NamesRegistry
|
31
|
+
{
|
32
|
+
private $names = [];
|
33
|
+
private static $letters;
|
34
|
+
private static $registry;
|
35
|
+
|
36
|
+
private function __construct()
|
24
37
|
{
|
25
|
-
|
38
|
+
|
26
39
|
}
|
27
40
|
|
28
|
-
|
41
|
+
/**
|
42
|
+
* Get NamesRegistry singleton
|
43
|
+
*
|
44
|
+
* @return NamesRegistry
|
45
|
+
*/
|
46
|
+
public static function connect()
|
29
47
|
{
|
30
|
-
|
48
|
+
if (empty(self::$registry)) {
|
49
|
+
self::$registry = new NamesRegistry();
|
50
|
+
self::$letters = range('A', 'Z');
|
51
|
+
}
|
52
|
+
return self::$registry;
|
31
53
|
}
|
32
54
|
|
33
|
-
|
55
|
+
/**
|
56
|
+
* Get new unique robot name
|
57
|
+
*
|
58
|
+
* @todo Names rotation not implemented. Task requires all robots
|
59
|
+
* to have unique names even if there are obsolete names.
|
60
|
+
* @todo If there are plans to use Robot::reset() more than at least 200-300k times,
|
61
|
+
* it should be better to generate the full list of possible names at __construct
|
62
|
+
* and randomly reduce it on demand.
|
63
|
+
* @todo No fallback in case of over 676000 names.
|
64
|
+
*
|
65
|
+
* @return string New Robot name *
|
66
|
+
*/
|
67
|
+
public function getNewName()
|
34
68
|
{
|
35
|
-
|
69
|
+
do {
|
70
|
+
shuffle(self::$letters);
|
71
|
+
$name = self::$letters[0] . self::$letters[1] . sprintf('%03d', mt_rand(0, 999));
|
72
|
+
} while (!empty($this->names[$name]));
|
73
|
+
$this->names[$name] = true;
|
74
|
+
return $name;
|
36
75
|
}
|
37
76
|
}
|
@@ -48,4 +48,27 @@ class RobotTest extends PHPUnit_Framework_TestCase
|
|
48
48
|
|
49
49
|
$this->assertRegExp('/\w{2}\d{3}/', $name2);
|
50
50
|
}
|
51
|
+
|
52
|
+
public function testNameArentRecycled()
|
53
|
+
{
|
54
|
+
$names = [];
|
55
|
+
|
56
|
+
for ($i = 0; $i < 10000; $i++) {
|
57
|
+
$name = $this->robot->getName();
|
58
|
+
$this->assertArrayNotHasKey($name, $names, sprintf('Name %s reissued after Reset.', $name));
|
59
|
+
$names[$name] = true;
|
60
|
+
$this->robot->reset();
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
public function testNameUniquenessManyRobots()
|
65
|
+
{
|
66
|
+
$names = [];
|
67
|
+
|
68
|
+
for ($i = 0; $i < 10000; $i++) {
|
69
|
+
$name = (new Robot())->getName();
|
70
|
+
$this->assertArrayNotHasKey($name, $names, sprintf('Name %s reissued after %d robots', $name, $i));
|
71
|
+
$names[$name] = true;
|
72
|
+
}
|
73
|
+
}
|
51
74
|
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
## Hints
|
2
|
+
For something a little different you might also try a solution with an `unfold` function.
|
3
|
+
You are probably already familiar with `foldLeft/Right`: "map" a whole collection into something else (usually a non-collection).
|
4
|
+
`unfoldLeft/Right` are the "inverse" operations: "map" something (usually a non-collection) into a collection.
|
5
|
+
So `unfold`ing is a logical addition to and part of the FP standard repertoire.
|
6
|
+
|
7
|
+
This exercise can be seen as a case for `unfold`ing: "map" an `Int` into a `String` (which is of course implicitly a `Seq[Char]`).
|
8
|
+
|
9
|
+
Unfortunately `unfoldLeft/Right` is not included in Scala's collection library.
|
10
|
+
But you can take the implementation from [here](http://daily-scala.blogspot.de/2009/09/unfoldleft-and-right.html).
|
data/tracks/swift/config.json
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
struct Transpose {
|
2
|
+
static func transpose(_ input: [String]) -> [String] {
|
3
|
+
let maxLineLength = input.map { $0.characters.count }.max()
|
4
|
+
|
5
|
+
guard let maxLength = maxLineLength else {
|
6
|
+
return []
|
7
|
+
}
|
8
|
+
|
9
|
+
var result = [String](repeatElement("", count: maxLength))
|
10
|
+
|
11
|
+
for i in 0..<maxLength {
|
12
|
+
for line in input {
|
13
|
+
if let start = line.index(line.startIndex, offsetBy: i, limitedBy: line.endIndex),
|
14
|
+
let end = line.index(start, offsetBy: 1, limitedBy: line.endIndex) {
|
15
|
+
let character = line[start..<end]
|
16
|
+
result[i].append(character)
|
17
|
+
} else {
|
18
|
+
result[i].append(" ")
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
return result.map { stripTrailingWhitespace($0) }
|
24
|
+
}
|
25
|
+
|
26
|
+
private static func stripTrailingWhitespace(_ input: String) -> String {
|
27
|
+
var result = input
|
28
|
+
|
29
|
+
while result.hasSuffix(" ") {
|
30
|
+
result.remove(at: result.index(before: result.endIndex))
|
31
|
+
}
|
32
|
+
|
33
|
+
return result
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,135 @@
|
|
1
|
+
#if swift(>=3.0)
|
2
|
+
import XCTest
|
3
|
+
#endif
|
4
|
+
|
5
|
+
class TransposeTest: XCTestCase {
|
6
|
+
|
7
|
+
func testEmptyInput() {
|
8
|
+
XCTAssertEqual(Transpose.transpose([]), [])
|
9
|
+
}
|
10
|
+
|
11
|
+
func testTwoCharactersInARow() {
|
12
|
+
XCTAssertEqual(Transpose.transpose(["A1"]), ["A", "1"])
|
13
|
+
}
|
14
|
+
|
15
|
+
func testTwoCharactersInAColumn() {
|
16
|
+
XCTAssertEqual(Transpose.transpose(["A", "1"]), ["A1"])
|
17
|
+
}
|
18
|
+
|
19
|
+
func testSimple() {
|
20
|
+
XCTAssertEqual(Transpose.transpose(["ABC", "123"]), ["A1", "B2", "C3"])
|
21
|
+
}
|
22
|
+
|
23
|
+
func testSingleLine() {
|
24
|
+
let expected = ["S", "i", "n", "g", "l", "e", "", "l", "i", "n", "e", "."]
|
25
|
+
XCTAssertEqual(Transpose.transpose(["Single line."]), expected)
|
26
|
+
}
|
27
|
+
|
28
|
+
func testFirstLineLongerThanSecondLine() {
|
29
|
+
let input = ["The fourth line.", "The fifth line."]
|
30
|
+
let expected = ["TT", "hh", "ee", "", "ff", "oi", "uf", "rt", "th", "h", " l", "li", "in", "ne", "e.", "."]
|
31
|
+
XCTAssertEqual(Transpose.transpose(input), expected)
|
32
|
+
}
|
33
|
+
|
34
|
+
func testSecondLineLongerThanFirstLine() {
|
35
|
+
let input = ["The first line.", "The second line."]
|
36
|
+
let expected = ["TT", "hh", "ee", "", "fs", "ie", "rc", "so", "tn", " d", "l", "il", "ni", "en", ".e", " ."]
|
37
|
+
XCTAssertEqual(Transpose.transpose(input), expected)
|
38
|
+
}
|
39
|
+
|
40
|
+
func testSquare() {
|
41
|
+
let input = ["HEART", "EMBER", "ABUSE", "RESIN", "TREND"]
|
42
|
+
let expected = ["HEART", "EMBER", "ABUSE", "RESIN", "TREND"]
|
43
|
+
XCTAssertEqual(Transpose.transpose(input), expected)
|
44
|
+
}
|
45
|
+
|
46
|
+
func testRectangle() {
|
47
|
+
let input = ["FRACTURE", "OUTLINED", "BLOOMING", "SEPTETTE"]
|
48
|
+
let expected = ["FOBS", "RULE", "ATOP", "CLOT", "TIME", "UNIT", "RENT", "EDGE"]
|
49
|
+
XCTAssertEqual(Transpose.transpose(input), expected)
|
50
|
+
}
|
51
|
+
|
52
|
+
func testTriangle() {
|
53
|
+
let input = ["T", "EE", "AAA", "SSSS", "EEEEE", "RRRRRR"]
|
54
|
+
let expected = ["TEASER", " EASER", " ASER", " SER", " ER", " R"]
|
55
|
+
XCTAssertEqual(Transpose.transpose(input), expected)
|
56
|
+
}
|
57
|
+
|
58
|
+
func testManyLines() {
|
59
|
+
let input = [
|
60
|
+
"Chor. Two households, both alike in dignity,",
|
61
|
+
"In fair Verona, where we lay our scene,",
|
62
|
+
"From ancient grudge break to new mutiny,",
|
63
|
+
"Where civil blood makes civil hands unclean.",
|
64
|
+
"From forth the fatal loins of these two foes",
|
65
|
+
"A pair of star-cross'd lovers take their life;",
|
66
|
+
"Whose misadventur'd piteous overthrows",
|
67
|
+
"Doth with their death bury their parents' strife.",
|
68
|
+
"The fearful passage of their death-mark'd love,",
|
69
|
+
"And the continuance of their parents' rage,",
|
70
|
+
"Which, but their children's end, naught could remove,",
|
71
|
+
"Is now the two hours' traffic of our stage;",
|
72
|
+
"The which if you with patient ears attend,",
|
73
|
+
"What here shall miss, our toil shall strive to mend."
|
74
|
+
]
|
75
|
+
|
76
|
+
let expected = [
|
77
|
+
"CIFWFAWDTAWITW",
|
78
|
+
"hnrhr hohnhshh",
|
79
|
+
"o oeopotedi ea",
|
80
|
+
"rfmrmash cn t",
|
81
|
+
".a e ie fthow",
|
82
|
+
" ia fr weh,whh",
|
83
|
+
"Trnco miae ie",
|
84
|
+
"w ciroitr btcr",
|
85
|
+
"oVivtfshfcuhhe",
|
86
|
+
" eeih a uote",
|
87
|
+
"hrnl sdtln is",
|
88
|
+
"oot ttvh tttfh",
|
89
|
+
"un bhaeepihw a",
|
90
|
+
"saglernianeoyl",
|
91
|
+
"e,ro -trsui ol",
|
92
|
+
"h uofcu sarhu",
|
93
|
+
"owddarrdan o m",
|
94
|
+
"lhg to'egccuwi",
|
95
|
+
"deemasdaeehris",
|
96
|
+
"sr als t ists",
|
97
|
+
",ebk 'phool'h,",
|
98
|
+
" reldi ffd",
|
99
|
+
"bweso tb rtpo",
|
100
|
+
"oea ileutterau",
|
101
|
+
"t kcnoorhhnatr",
|
102
|
+
"hl isvuyee'fi",
|
103
|
+
" atv es iisfet",
|
104
|
+
"ayoior trr ino",
|
105
|
+
"l lfsoh ecti",
|
106
|
+
"ion vedpn l",
|
107
|
+
"kuehtteieadoe",
|
108
|
+
"erwaharrar,fas",
|
109
|
+
" nekt te rh",
|
110
|
+
"ismdsehphnnosa",
|
111
|
+
"ncuse ra-tau l",
|
112
|
+
" et tormsural",
|
113
|
+
"dniuthwea'g t",
|
114
|
+
"iennwesnr hsts",
|
115
|
+
"g,ycoi tkrttet",
|
116
|
+
"n ,l r s'a anr",
|
117
|
+
"i ef 'dgcgdi",
|
118
|
+
"t aol eoe,v",
|
119
|
+
"y nei sl,u; e",
|
120
|
+
", .sf to l",
|
121
|
+
" e rv d t",
|
122
|
+
" ; ie o",
|
123
|
+
" f, r",
|
124
|
+
" e e m",
|
125
|
+
" . m e",
|
126
|
+
" o n",
|
127
|
+
" v d",
|
128
|
+
" e .",
|
129
|
+
" ,"
|
130
|
+
]
|
131
|
+
|
132
|
+
XCTAssertEqual(Transpose.transpose(input), expected)
|
133
|
+
}
|
134
|
+
|
135
|
+
}
|
@@ -127,6 +127,8 @@
|
|
127
127
|
E90D62081C653ADC00C266D3 /* PalindromeProductsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90D62071C653ADC00C266D3 /* PalindromeProductsTest.swift */; };
|
128
128
|
E90DE39C1D3E812300F3B881 /* AllYourBaseExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90DE39B1D3E812300F3B881 /* AllYourBaseExample.swift */; };
|
129
129
|
E90DE39E1D3E818000F3B881 /* AllYourBaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E90DE39D1D3E818000F3B881 /* AllYourBaseTest.swift */; };
|
130
|
+
E9443F251DF5C02700A468B7 /* TransposeExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9443F241DF5C02700A468B7 /* TransposeExample.swift */; };
|
131
|
+
E9443F271DF5C04000A468B7 /* TransposeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9443F261DF5C04000A468B7 /* TransposeTest.swift */; };
|
130
132
|
E94BDECF1C510E68009318BB /* BinarySearchExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94BDECD1C510E68009318BB /* BinarySearchExample.swift */; };
|
131
133
|
E94BDED01C510E68009318BB /* BinarySearchTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94BDECE1C510E68009318BB /* BinarySearchTest.swift */; };
|
132
134
|
E951B6BD1D466045009EB5B6 /* BracketPushExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E951B6BC1D466045009EB5B6 /* BracketPushExample.swift */; };
|
@@ -285,6 +287,8 @@
|
|
285
287
|
E90D62071C653ADC00C266D3 /* PalindromeProductsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = PalindromeProductsTest.swift; path = "palindrome-products/PalindromeProductsTest.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
286
288
|
E90DE39B1D3E812300F3B881 /* AllYourBaseExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AllYourBaseExample.swift; path = "../all-your-base/AllYourBaseExample.swift"; sourceTree = "<group>"; };
|
287
289
|
E90DE39D1D3E818000F3B881 /* AllYourBaseTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AllYourBaseTest.swift; path = "../all-your-base/AllYourBaseTest.swift"; sourceTree = "<group>"; };
|
290
|
+
E9443F241DF5C02700A468B7 /* TransposeExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TransposeExample.swift; path = ../transpose/TransposeExample.swift; sourceTree = "<group>"; };
|
291
|
+
E9443F261DF5C04000A468B7 /* TransposeTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TransposeTest.swift; path = ../transpose/TransposeTest.swift; sourceTree = "<group>"; };
|
288
292
|
E94BDECD1C510E68009318BB /* BinarySearchExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BinarySearchExample.swift; path = "binary-search/BinarySearchExample.swift"; sourceTree = "<group>"; };
|
289
293
|
E94BDECE1C510E68009318BB /* BinarySearchTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = BinarySearchTest.swift; path = "binary-search/BinarySearchTest.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
290
294
|
E951B6BC1D466045009EB5B6 /* BracketPushExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BracketPushExample.swift; path = "../bracket-push/BracketPushExample.swift"; sourceTree = "<group>"; };
|
@@ -397,6 +401,7 @@
|
|
397
401
|
1E9A63701C506EFC00E28AE1 /* strain */,
|
398
402
|
1E9A63731C506EFC00E28AE1 /* sum-of-multiples */,
|
399
403
|
1E9A63761C506EFC00E28AE1 /* tournament */,
|
404
|
+
E9443F201DF5BFBF00A468B7 /* transpose */,
|
400
405
|
1E9A63791C506EFC00E28AE1 /* triangle */,
|
401
406
|
1E9A637C1C506EFC00E28AE1 /* trinary */,
|
402
407
|
1E9A637F1C506EFC00E28AE1 /* twelve-days */,
|
@@ -983,6 +988,16 @@
|
|
983
988
|
path = acronym;
|
984
989
|
sourceTree = "<group>";
|
985
990
|
};
|
991
|
+
E9443F201DF5BFBF00A468B7 /* transpose */ = {
|
992
|
+
isa = PBXGroup;
|
993
|
+
children = (
|
994
|
+
E9443F241DF5C02700A468B7 /* TransposeExample.swift */,
|
995
|
+
E9443F261DF5C04000A468B7 /* TransposeTest.swift */,
|
996
|
+
);
|
997
|
+
name = transpose;
|
998
|
+
path = tournament;
|
999
|
+
sourceTree = "<group>";
|
1000
|
+
};
|
986
1001
|
E94BDECB1C510DF4009318BB /* binary-search */ = {
|
987
1002
|
isa = PBXGroup;
|
988
1003
|
children = (
|
@@ -1288,12 +1303,14 @@
|
|
1288
1303
|
E9AFA17A1C614DA0006AD72D /* HouseTest.swift in Sources */,
|
1289
1304
|
1E9A63B11C506EFD00E28AE1 /* LinkedListTest.swift in Sources */,
|
1290
1305
|
1E9A63921C506EFD00E28AE1 /* BinaryExample.swift in Sources */,
|
1306
|
+
E9443F271DF5C04000A468B7 /* TransposeTest.swift in Sources */,
|
1291
1307
|
1E9A638F1C506EFD00E28AE1 /* AnagramTest.swift in Sources */,
|
1292
1308
|
1E9A63D51C506EFD00E28AE1 /* SecretHandshakeTest.swift in Sources */,
|
1293
1309
|
1E9A63BA1C506EFD00E28AE1 /* OctalExample.swift in Sources */,
|
1294
1310
|
1E9A63C81C506EFD00E28AE1 /* RaindropsExample.swift in Sources */,
|
1295
1311
|
E951B6BF1D466058009EB5B6 /* BracketPushTest.swift in Sources */,
|
1296
1312
|
E9AFA1601C5BFC57006AD72D /* LargestSeriesProductExample.swift in Sources */,
|
1313
|
+
E9443F251DF5C02700A468B7 /* TransposeExample.swift in Sources */,
|
1297
1314
|
E9AFA16D1C5EF4EA006AD72D /* MatrixTest.swift in Sources */,
|
1298
1315
|
1E9A638E1C506EFD00E28AE1 /* AnagramExample.swift in Sources */,
|
1299
1316
|
1E9A63A01C506EFD00E28AE1 /* GigasecondExample.swift in Sources */,
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trackler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.3.
|
4
|
+
version: 2.0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katrina Owen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -3207,6 +3207,7 @@ files:
|
|
3207
3207
|
- tracks/haskell/exercises/pig-latin/src/PigLatin.hs
|
3208
3208
|
- tracks/haskell/exercises/pig-latin/stack.yaml
|
3209
3209
|
- tracks/haskell/exercises/pig-latin/test/Tests.hs
|
3210
|
+
- tracks/haskell/exercises/pov/.dummylink
|
3210
3211
|
- tracks/haskell/exercises/pov/examples/success-standard/package.yaml
|
3211
3212
|
- tracks/haskell/exercises/pov/examples/success-standard/src/POV.hs
|
3212
3213
|
- tracks/haskell/exercises/pov/package.yaml
|
@@ -4946,6 +4947,7 @@ files:
|
|
4946
4947
|
- tracks/ocaml/tools/test-generator/templates/hamming/template.ml
|
4947
4948
|
- tracks/ocaml/tools/test-generator/templates/hello-world/template.ml
|
4948
4949
|
- tracks/ocaml/tools/test-generator/templates/leap/template.ml
|
4950
|
+
- tracks/ocaml/tools/test-generator/templates/minesweeper/template.ml
|
4949
4951
|
- tracks/ocaml/tools/test-generator/templates/raindrops/template.ml
|
4950
4952
|
- tracks/ocaml/tools/test-generator/templates/say/template.ml
|
4951
4953
|
- tracks/ocaml/tools/test-generator/templates/word-count/template.ml
|
@@ -6319,6 +6321,7 @@ files:
|
|
6319
6321
|
- tracks/scala/exercises/forth/src/main/scala/.keep
|
6320
6322
|
- tracks/scala/exercises/forth/src/main/scala/ForthEvaluator.scala
|
6321
6323
|
- tracks/scala/exercises/forth/src/test/scala/ForthTest.scala
|
6324
|
+
- tracks/scala/exercises/gigasecond/HINTS.md
|
6322
6325
|
- tracks/scala/exercises/gigasecond/build.sbt
|
6323
6326
|
- tracks/scala/exercises/gigasecond/example.scala
|
6324
6327
|
- tracks/scala/exercises/gigasecond/src/main/scala/.keep
|
@@ -6456,6 +6459,7 @@ files:
|
|
6456
6459
|
- tracks/scala/exercises/robot-simulator/example.scala
|
6457
6460
|
- tracks/scala/exercises/robot-simulator/src/main/scala/.keep
|
6458
6461
|
- tracks/scala/exercises/robot-simulator/src/test/scala/RobotTest.scala
|
6462
|
+
- tracks/scala/exercises/roman-numerals/HINTS.md
|
6459
6463
|
- tracks/scala/exercises/roman-numerals/build.sbt
|
6460
6464
|
- tracks/scala/exercises/roman-numerals/example.scala
|
6461
6465
|
- tracks/scala/exercises/roman-numerals/src/main/scala/.keep
|
@@ -6766,6 +6770,8 @@ files:
|
|
6766
6770
|
- tracks/swift/exercises/sum-of-multiples/SumOfMultiplesTest.swift
|
6767
6771
|
- tracks/swift/exercises/tournament/TournamentExample.swift
|
6768
6772
|
- tracks/swift/exercises/tournament/TournamentTest.swift
|
6773
|
+
- tracks/swift/exercises/transpose/TransposeExample.swift
|
6774
|
+
- tracks/swift/exercises/transpose/TransposeTest.swift
|
6769
6775
|
- tracks/swift/exercises/triangle/TriangleExample.swift
|
6770
6776
|
- tracks/swift/exercises/triangle/TriangleTest.swift
|
6771
6777
|
- tracks/swift/exercises/trinary/TrinaryExample.swift
|
@@ -1 +0,0 @@
|
|
1
|
-
tracks/haskell/exercises/pov/../../common/stack.yaml
|