trackler 2.0.8.17 → 2.0.8.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/exercises/forth/canonical-data.json +307 -321
- data/common/exercises/largest-series-product/canonical-data.json +139 -122
- data/common/exercises/list-ops/canonical-data.json +162 -141
- data/common/exercises/markdown/canonical-data.json +15 -14
- data/common/exercises/pov/canonical-data.json +264 -116
- data/common/exercises/prime-factors/canonical-data.json +51 -40
- data/common/exercises/rail-fence-cipher/canonical-data.json +56 -44
- data/common/exercises/react/canonical-data.json +18 -4
- data/common/exercises/rectangles/canonical-data.json +16 -1
- data/common/exercises/rotational-cipher/canonical-data.json +81 -67
- data/common/exercises/run-length-encoding/canonical-data.json +89 -71
- data/common/exercises/space-age/canonical-data.json +61 -45
- data/common/exercises/sublist/canonical-data.json +136 -99
- data/common/exercises/transpose/canonical-data.json +207 -194
- data/common/exercises/variable-length-quantity/canonical-data.json +171 -141
- data/lib/trackler/version.rb +1 -1
- data/tracks/csharp/exercises/diamond/HINTS.md +9 -0
- data/tracks/go/README.md +3 -0
- data/tracks/go/exercises/queen-attack/queen_attack_test.go +1 -1
- data/tracks/haskell/exercises/hamming/src/Hamming.hs +2 -1
- data/tracks/java/exercises/flatten-array/src/test/java/FlattenerTest.java +5 -0
- data/tracks/ocaml/exercises/anagram/test.ml +2 -2
- data/tracks/ocaml/tools/test-generator/src/controller.ml +7 -2
- data/tracks/ocaml/tools/test-generator/src/parser.ml +31 -18
- data/tracks/ocaml/tools/test-generator/src/template.ml +10 -8
- data/tracks/ocaml/tools/test-generator/src/utils.ml +11 -0
- data/tracks/ocaml/tools/test-generator/templates/phone-number/template.ml +4 -5
- data/tracks/ocaml/tools/test-generator/test/beer-song.json +77 -0
- data/tracks/ocaml/tools/test-generator/test/difference_of_squares.json +76 -62
- data/tracks/ocaml/tools/test-generator/test/parser_test.ml +11 -9
- data/tracks/ocaml/tools/test-generator/test/template_test.ml +2 -2
- metadata +4 -2
@@ -1,125 +1,142 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
"exercise": "largest-series-product",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"comments": [
|
5
|
+
"A negative expected value means the input is invalid.",
|
6
|
+
"Different languages may handle this differently.",
|
7
|
+
"e.g. raise exceptions, return (int, error), return Option<int>, etc.",
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
9
|
+
"Some languages specifically test the string->digits conversion",
|
10
|
+
"and the 'slices of size N' operation.",
|
11
|
+
"These cases *deliberately* do not cover those two operations.",
|
12
|
+
"Those are implementation details.",
|
13
|
+
"Testing them constrains implementations,",
|
14
|
+
"and not all implementations use these operations.",
|
15
|
+
"e.g. The implementation which makes a single pass through the digits."
|
16
|
+
],
|
17
|
+
"cases": [
|
18
|
+
{
|
19
|
+
"description": "finds the largest product if span equals length",
|
20
|
+
"property": "largestProduct",
|
21
|
+
"digits": "29",
|
22
|
+
"span": 2,
|
23
|
+
"expected": 18
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"description": "can find the largest product of 2 with numbers in order",
|
27
|
+
"property": "largestProduct",
|
28
|
+
"digits": "0123456789",
|
29
|
+
"span": 2,
|
30
|
+
"expected": 72
|
31
|
+
},
|
32
|
+
{
|
33
|
+
"description": "can find the largest product of 2",
|
34
|
+
"property": "largestProduct",
|
35
|
+
"digits": "576802143",
|
36
|
+
"span": 2,
|
37
|
+
"expected": 48
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"description": "can find the largest product of 3 with numbers in order",
|
41
|
+
"property": "largestProduct",
|
42
|
+
"digits": "0123456789",
|
43
|
+
"span": 3,
|
44
|
+
"expected": 504
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"description": "can find the largest product of 3",
|
48
|
+
"property": "largestProduct",
|
49
|
+
"digits": "1027839564",
|
50
|
+
"span": 3,
|
51
|
+
"expected": 270
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"description": "can find the largest product of 5 with numbers in order",
|
55
|
+
"property": "largestProduct",
|
56
|
+
"digits": "0123456789",
|
57
|
+
"span": 5,
|
58
|
+
"expected": 15120
|
59
|
+
},
|
60
|
+
{
|
61
|
+
"description": "can get the largest product of a big number",
|
62
|
+
"property": "largestProduct",
|
63
|
+
"digits": "73167176531330624919225119674426574742355349194934",
|
64
|
+
"span": 6,
|
65
|
+
"expected": 23520
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"description": "reports zero if the only digits are zero",
|
69
|
+
"property": "largestProduct",
|
70
|
+
"digits": "0000",
|
71
|
+
"span": 2,
|
72
|
+
"expected": 0
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"description": "reports zero if all spans include zero",
|
76
|
+
"property": "largestProduct",
|
77
|
+
"digits": "99099",
|
78
|
+
"span": 3,
|
79
|
+
"expected": 0
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"description": "rejects span longer than string length",
|
83
|
+
"property": "largestProduct",
|
84
|
+
"digits": "123",
|
85
|
+
"span": 4,
|
86
|
+
"expected": -1
|
87
|
+
},
|
88
|
+
{
|
89
|
+
"comments": [
|
90
|
+
"There may be some confusion about whether this should be 1 or error.",
|
91
|
+
"The reasoning for it being 1 is this:",
|
92
|
+
"There is one 0-character string contained in the empty string.",
|
93
|
+
"That's the empty string itself.",
|
94
|
+
"The empty product is 1 (the identity for multiplication).",
|
95
|
+
"Therefore LSP('', 0) is 1.",
|
96
|
+
"It's NOT the case that LSP('', 0) takes max of an empty list.",
|
97
|
+
"So there is no error.",
|
98
|
+
"Compare against LSP('123', 4):",
|
99
|
+
"There are zero 4-character strings in '123'.",
|
100
|
+
"So LSP('123', 4) really DOES take the max of an empty list.",
|
101
|
+
"So LSP('123', 4) errors and LSP('', 0) does NOT."
|
102
|
+
],
|
103
|
+
"description": "reports 1 for empty string and empty product (0 span)",
|
104
|
+
"property": "largestProduct",
|
105
|
+
"digits": "",
|
106
|
+
"span": 0,
|
107
|
+
"expected": 1
|
108
|
+
},
|
109
|
+
{
|
110
|
+
"comments": [
|
111
|
+
"As above, there is one 0-character string in '123'.",
|
112
|
+
"So again no error. It's the empty product, 1."
|
113
|
+
],
|
114
|
+
"description": "reports 1 for nonempty string and empty product (0 span)",
|
115
|
+
"property": "largestProduct",
|
116
|
+
"digits": "123",
|
117
|
+
"span": 0,
|
118
|
+
"expected": 1
|
119
|
+
},
|
120
|
+
{
|
121
|
+
"description": "rejects empty string and nonzero span",
|
122
|
+
"property": "largestProduct",
|
123
|
+
"digits": "",
|
124
|
+
"span": 1,
|
125
|
+
"expected": -1
|
126
|
+
},
|
127
|
+
{
|
128
|
+
"description": "rejects invalid character in digits",
|
129
|
+
"property": "largestProduct",
|
130
|
+
"digits": "1234a5",
|
131
|
+
"span": 2,
|
132
|
+
"expected": -1
|
133
|
+
},
|
134
|
+
{
|
135
|
+
"description": "rejects negative span",
|
136
|
+
"property": "largestProduct",
|
137
|
+
"digits": "12345",
|
138
|
+
"span": -1,
|
139
|
+
"expected": -1
|
140
|
+
}
|
141
|
+
]
|
125
142
|
}
|
@@ -1,147 +1,168 @@
|
|
1
1
|
{
|
2
|
-
"
|
2
|
+
"exercise": "list-ops",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"comments": [
|
3
5
|
"Though there are no specifications here for dealing with large lists,",
|
4
6
|
"implementers may add tests for handling large lists to ensure that the",
|
5
7
|
"solutions have thought about performance concerns."
|
6
8
|
],
|
7
|
-
"
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
9
|
+
"cases": [
|
10
|
+
{
|
11
|
+
"description": "append entries to a list and return the new list",
|
12
|
+
"cases": [
|
13
|
+
{
|
14
|
+
"description": "empty lists",
|
15
|
+
"property": "append",
|
16
|
+
"list1": [],
|
17
|
+
"list2": [],
|
18
|
+
"expected": []
|
19
|
+
},
|
20
|
+
{
|
21
|
+
"description": "empty list to list",
|
22
|
+
"property": "append",
|
23
|
+
"list1": [],
|
24
|
+
"list2": [1, 2, 3, 4],
|
25
|
+
"expected": [1, 2, 3, 4]
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"description": "non-empty lists",
|
29
|
+
"property": "append",
|
30
|
+
"list1": [1, 2],
|
31
|
+
"list2": [2, 3, 4, 5],
|
32
|
+
"expected": [1, 2, 2, 3, 4, 5]
|
33
|
+
}
|
34
|
+
]
|
35
|
+
},
|
36
|
+
{
|
37
|
+
"description": "concat lists and lists of list into a new list",
|
38
|
+
"cases": [
|
39
|
+
{
|
40
|
+
"description": "empty list",
|
41
|
+
"property": "concat",
|
42
|
+
"lists": [],
|
43
|
+
"expected": []
|
44
|
+
},
|
45
|
+
{
|
46
|
+
"description": "list of lists",
|
47
|
+
"property": "concat",
|
48
|
+
"lists": [[1, 2], [3], [], [4, 5, 6]],
|
49
|
+
"expected": [1, 2, 3, 4, 5, 6]
|
50
|
+
}
|
51
|
+
]
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"description": "filter list returning only values that satisfy the filter function",
|
55
|
+
"cases": [
|
56
|
+
{
|
57
|
+
"description": "empty list",
|
58
|
+
"property": "filter",
|
59
|
+
"list": [],
|
60
|
+
"function": "value modulo 2 == 1",
|
61
|
+
"expected": []
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"description": "non-empty list",
|
65
|
+
"property": "filter",
|
66
|
+
"list": [1, 2, 3, 5],
|
67
|
+
"function": "value modulo 2 == 1",
|
68
|
+
"expected": [1, 3, 5]
|
69
|
+
}
|
70
|
+
]
|
71
|
+
},
|
72
|
+
{
|
73
|
+
"description": "returns the length of a list",
|
74
|
+
"cases": [
|
75
|
+
{
|
76
|
+
"description": "empty list",
|
77
|
+
"property": "length",
|
78
|
+
"list": [],
|
79
|
+
"expected": 0
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"description": "non-empty list",
|
83
|
+
"property": "length",
|
84
|
+
"list": [1, 2, 3, 4],
|
85
|
+
"expected": 4
|
86
|
+
}
|
87
|
+
]
|
88
|
+
},
|
89
|
+
{
|
90
|
+
"description": "return a list of elements whos values equal the list value transformed by the mapping function",
|
91
|
+
"cases": [
|
92
|
+
{
|
93
|
+
"description": "empty list",
|
94
|
+
"property": "map",
|
95
|
+
"list": [],
|
96
|
+
"function": "value + 1",
|
97
|
+
"expected": []
|
98
|
+
},
|
99
|
+
{
|
100
|
+
"description": "non-empty list",
|
101
|
+
"property": "map",
|
102
|
+
"list": [1, 3, 5, 7],
|
103
|
+
"function": "value + 1",
|
104
|
+
"expected": [2, 4, 6, 8]
|
105
|
+
}
|
106
|
+
]
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"description": "folds (reduces) the given list from the left with a function",
|
110
|
+
"cases": [
|
111
|
+
{
|
112
|
+
"description": "empty list",
|
113
|
+
"property": "foldl",
|
114
|
+
"list": [],
|
115
|
+
"initial": 2,
|
116
|
+
"function": "value / accumulator",
|
117
|
+
"expected": 2
|
118
|
+
},
|
119
|
+
{
|
120
|
+
"description": "division of integers",
|
121
|
+
"property": "foldl",
|
122
|
+
"list": [1, 2, 3, 4],
|
123
|
+
"initial": 24,
|
124
|
+
"function": "value / accumulator",
|
125
|
+
"expected": 64
|
126
|
+
}
|
127
|
+
]
|
128
|
+
},
|
129
|
+
{
|
130
|
+
"description": "folds (reduces) the given list from the right with a function",
|
131
|
+
"cases": [
|
132
|
+
{
|
133
|
+
"description": "empty list",
|
134
|
+
"property": "foldr",
|
135
|
+
"list": [],
|
136
|
+
"initial": 2,
|
137
|
+
"function": "value / accumulator",
|
138
|
+
"expected": 2
|
139
|
+
},
|
140
|
+
{
|
141
|
+
"description": "division of integers",
|
142
|
+
"property": "foldr",
|
143
|
+
"list": [1, 2, 3, 4],
|
144
|
+
"initial": 24,
|
145
|
+
"function": "value / accumulator",
|
146
|
+
"expected": 9
|
147
|
+
}
|
148
|
+
]
|
149
|
+
},
|
150
|
+
{
|
151
|
+
"description": "reverse the elements of the list",
|
152
|
+
"cases": [
|
153
|
+
{
|
154
|
+
"description": "empty list",
|
155
|
+
"property": "reverse",
|
156
|
+
"list": [],
|
157
|
+
"expected": []
|
158
|
+
},
|
159
|
+
{
|
160
|
+
"description": "non-empty list",
|
161
|
+
"property": "reverse",
|
162
|
+
"list": [1, 3, 5, 7],
|
163
|
+
"expected": [7, 5, 3, 1]
|
164
|
+
}
|
165
|
+
]
|
166
|
+
}
|
167
|
+
]
|
147
168
|
}
|