trackler 2.0.8.10 → 2.0.8.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/exercises/palindrome-products/description.md +1 -1
- data/lib/trackler/version.rb +1 -1
- data/tracks/delphi/exercises/bowling/uBowlingExample.pas +52 -23
- data/tracks/delphi/exercises/bowling/uBowlingTests.pas +237 -46
- data/tracks/go/exercises/forth/example.go +36 -37
- data/tracks/go/exercises/kindergarten-garden/kindergarten_garden_test.go +2 -2
- data/tracks/java/exercises/allergies/src/test/java/AllergiesTest.java +2 -0
- data/tracks/scala/config.json +10 -0
- data/tracks/scala/exercises/simple-linked-list/build.sbt +3 -0
- data/tracks/scala/exercises/simple-linked-list/example.scala +95 -0
- data/tracks/scala/exercises/simple-linked-list/src/main/scala/SimpleLinkedList.scala +8 -0
- data/tracks/scala/exercises/simple-linked-list/src/test/scala/SimpleLinkedListTest.scala +108 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7985975e695c967206c6399587638d7b92f6ddeb
|
4
|
+
data.tar.gz: f605cb15bcc556c8f153ebf0aa71768b773709c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f6cd5026c972237c9495b8acd567fa1ac65fc949bcf2da45c797526fe5057cea00c78bd433f840c8003da55f729e675c184a65d4d6510aa589f31288b22350f
|
7
|
+
data.tar.gz: 8687e2946dec0948f8a7800850103074d894c24aba6d92a530ea452672788f7014abf9a3e5d03fcffb619a5e1cbd845f51784451eaad4444a0493c7240a40ba9
|
@@ -27,4 +27,4 @@ The largest product is `9`. It's factors are `(1, 9)`, `(3, 3)`, and `(9, 1)`.
|
|
27
27
|
Given the range `[10, 99]` (both inclusive)...
|
28
28
|
|
29
29
|
The smallest palindrome product is `121`. It's factors are `(11, 11)`.
|
30
|
-
The largest palindrome product is `9009`. It's factors are `(
|
30
|
+
The largest palindrome product is `9009`. It's factors are `(91, 99)` and `(99, 91)`.
|
data/lib/trackler/version.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
unit uBowling;
|
2
2
|
|
3
3
|
interface
|
4
|
-
uses System.Generics.Collections;
|
5
4
|
|
6
5
|
type
|
7
6
|
IBowlingGame = interface(IInvokable)
|
@@ -13,18 +12,22 @@ type
|
|
13
12
|
function NewBowlingGame: IBowlingGame;
|
14
13
|
|
15
14
|
implementation
|
15
|
+
uses System.SysUtils, System.Math, System.Generics.Collections;
|
16
16
|
|
17
17
|
type
|
18
18
|
TBowlingGame = class(TInterfacedObject, IBowlingGame)
|
19
19
|
private
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
var
|
21
|
+
fRolls: TList<integer>;
|
22
|
+
const
|
23
|
+
fNumberOfFrames = 10;
|
24
|
+
fMaximumFrameScore = 10;
|
23
25
|
function IsStrike(aFrameIndex: integer): Boolean;
|
24
26
|
function IsSpare(aFrameIndex: integer): Boolean;
|
25
27
|
function StrikeBonus(aFrameIndex: integer): integer;
|
26
28
|
function SpareBonus(aFrameIndex: integer): integer;
|
27
29
|
function SumOfPinsInFrame(aFrameIndex: integer): integer;
|
30
|
+
function CorrectNumberOfRolls(aFrameIndex: integer): boolean;
|
28
31
|
public
|
29
32
|
constructor create;
|
30
33
|
function Score: integer;
|
@@ -38,8 +41,6 @@ end;
|
|
38
41
|
|
39
42
|
constructor TBowlingGame.create;
|
40
43
|
begin
|
41
|
-
fNumberOfFrames := 10;
|
42
|
-
fMaximumFrameScore := 10;
|
43
44
|
fRolls := TList<integer>.Create;
|
44
45
|
end;
|
45
46
|
|
@@ -52,29 +53,52 @@ function TBowlingGame.Score: integer;
|
|
52
53
|
var lFrameIndex: integer;
|
53
54
|
i: integer;
|
54
55
|
lScore: integer;
|
56
|
+
lStrikeBonus: integer;
|
57
|
+
lFrameScore: integer;
|
55
58
|
begin
|
56
59
|
lScore := 0;
|
57
60
|
lFrameIndex := 0;
|
58
|
-
|
59
|
-
|
60
|
-
if IsStrike(lFrameIndex) then
|
61
|
+
try
|
62
|
+
for i := 1 to fNumberOfFrames do
|
61
63
|
begin
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
64
|
+
if fRolls.Count <= lFrameIndex then
|
65
|
+
raise EArgumentException.Create('Not a proper game');
|
66
|
+
|
67
|
+
if IsStrike(lFrameIndex) then
|
68
|
+
begin
|
69
|
+
if (fRolls.Count <= lFrameIndex + 2) then
|
70
|
+
raise EArgumentException.Create('Not a proper game');
|
71
|
+
|
72
|
+
lStrikeBonus := StrikeBonus(lFrameIndex);
|
73
|
+
if (lStrikeBonus > fMaximumFrameScore) and not IsStrike(lFrameIndex + 1) then
|
74
|
+
raise EArgumentException.Create('Not a proper game');
|
75
|
+
|
76
|
+
lScore := lScore + 10 + lStrikeBonus;
|
77
|
+
inc(lFrameIndex, ifthen(i = fNumberOfFrames, 3, 1));
|
78
|
+
end
|
79
|
+
else
|
80
|
+
if IsSpare(lFrameIndex) then
|
81
|
+
begin
|
82
|
+
if (fRolls.Count <= lFrameIndex + 2) then
|
83
|
+
raise EArgumentException.Create('Not a proper game');
|
84
|
+
|
85
|
+
lScore := lScore + 10 + SpareBonus(lFrameIndex);
|
86
|
+
inc(lFrameIndex, ifthen(i = fNumberOfFrames, 3, 2));
|
87
|
+
end
|
88
|
+
else
|
89
|
+
begin
|
90
|
+
lFrameScore := SumOfPinsInFrame(lFrameIndex);
|
91
|
+
if (lFrameScore < 0) or (lFrameScore > 10) then
|
92
|
+
raise EArgumentException.Create('Not a proper game');
|
93
|
+
|
94
|
+
lScore := lScore + lFrameScore;
|
95
|
+
inc(lFrameIndex, 2);
|
96
|
+
end;
|
75
97
|
end;
|
98
|
+
result := ifthen(CorrectNumberOfRolls(lFrameIndex), lScore, -1);
|
99
|
+
except
|
100
|
+
result := -1;
|
76
101
|
end;
|
77
|
-
result := lScore;
|
78
102
|
end;
|
79
103
|
|
80
104
|
function TBowlingGame.IsStrike(aFrameIndex: Integer): Boolean;
|
@@ -102,4 +126,9 @@ begin
|
|
102
126
|
result := fRolls[aFrameIndex] + fRolls[aFrameIndex + 1];
|
103
127
|
end;
|
104
128
|
|
129
|
+
function TBowlingGame.CorrectNumberOfRolls(aFrameIndex: Integer): boolean;
|
130
|
+
begin
|
131
|
+
result := aFrameIndex = fRolls.Count;
|
132
|
+
end;
|
133
|
+
|
105
134
|
end.
|
@@ -10,90 +10,281 @@ type
|
|
10
10
|
[TestFixture]
|
11
11
|
BowlingTests = class(TObject)
|
12
12
|
private
|
13
|
-
class
|
14
|
-
class procedure RollSpare(game: IBowlingGame); static;
|
15
|
-
class procedure RollStrike(game: IBowlingGame); static;
|
13
|
+
class function RollMany(pins: array of integer; game: IBowlingGame): IBowlingGame; static;
|
16
14
|
public
|
17
15
|
[Test]
|
18
|
-
|
19
|
-
|
16
|
+
procedure Should_be_able_to_score_a_game_with_all_zeros;
|
17
|
+
|
18
|
+
[Test]
|
19
|
+
[Ignore('Comment this line to run this test')]
|
20
|
+
procedure Should_be_able_to_score_a_game_with_no_strikes_or_spares;
|
21
|
+
|
22
|
+
[Test]
|
23
|
+
[Ignore('Comment this line to run this test')]
|
24
|
+
procedure A_spare_followed_by_zeros_is_worth_ten_points;
|
25
|
+
|
26
|
+
[Test]
|
27
|
+
[Ignore('Comment this line to run this test')]
|
28
|
+
procedure Points_scored_in_the_roll_after_a_spare_are_counted_twice;
|
29
|
+
|
30
|
+
[Test]
|
31
|
+
[Ignore('Comment this line to run this test')]
|
32
|
+
procedure Consecutive_spares_each_get_a_one_roll_bonus;
|
33
|
+
|
34
|
+
[Test]
|
35
|
+
[Ignore('Comment this line to run this test')]
|
36
|
+
procedure A_spare_in_the_last_frame_gets_a_one_roll_bonus_that_is_counted_once;
|
37
|
+
|
38
|
+
[Test]
|
39
|
+
[Ignore('Comment this line to run this test')]
|
40
|
+
procedure A_strike_earns_ten_points_in_frame_with_a_single_roll;
|
41
|
+
|
42
|
+
[Test]
|
43
|
+
[Ignore('Comment this line to run this test')]
|
44
|
+
procedure Points_scored_in_the_two_rolls_after_a_strike_are_counted_twice_as_a_bonus;
|
45
|
+
|
46
|
+
[Test]
|
47
|
+
[Ignore('Comment this line to run this test')]
|
48
|
+
procedure Consecutive_strikes_each_get_the_two_roll_bonus;
|
49
|
+
|
50
|
+
[Test]
|
51
|
+
[Ignore('Comment this line to run this test')]
|
52
|
+
procedure A_strike_in_the_last_frame_gets_a_two_roll_bonus_that_is_counted_once;
|
53
|
+
|
54
|
+
[Test]
|
55
|
+
[Ignore('Comment this line to run this test')]
|
56
|
+
procedure Rolling_a_spare_with_the_two_roll_bonus_does_not_get_a_bonus_roll;
|
57
|
+
|
58
|
+
[Test]
|
59
|
+
[Ignore('Comment this line to run this test')]
|
60
|
+
procedure Strikes_with_the_two_roll_bonus_do_not_get_bonus_rolls;
|
61
|
+
|
62
|
+
[Test]
|
63
|
+
[Ignore('Comment this line to run this test')]
|
64
|
+
procedure A_strike_with_the_one_roll_bonus_after_a_spare_in_the_last_frame_does_not_get_a_bonus;
|
65
|
+
|
66
|
+
[Test]
|
67
|
+
[Ignore('Comment this line to run this test')]
|
68
|
+
procedure All_strikes_is_a_perfect_game;
|
69
|
+
|
70
|
+
[Test]
|
71
|
+
[Ignore('Comment this line to run this test')]
|
72
|
+
procedure Rolls_can_not_score_negative_points;
|
73
|
+
|
74
|
+
[Test]
|
75
|
+
[Ignore('Comment this line to run this test')]
|
76
|
+
procedure A_roll_can_not_score_more_than_10_points;
|
77
|
+
|
78
|
+
[Test]
|
79
|
+
[Ignore('Comment this line to run this test')]
|
80
|
+
procedure Two_rolls_in_a_frame_can_not_score_more_than_10_points;
|
81
|
+
|
82
|
+
[Test]
|
83
|
+
[Ignore('Comment this line to run this test')]
|
84
|
+
procedure Two_bonus_rolls_after_a_strike_in_the_last_frame_can_not_score_more_than_10_points;
|
85
|
+
|
20
86
|
[Test]
|
21
|
-
[Ignore]
|
22
|
-
procedure
|
87
|
+
[Ignore('Comment this line to run this test')]
|
88
|
+
procedure An_unstarted_game_can_not_be_scored;
|
89
|
+
|
90
|
+
[Test]
|
91
|
+
[Ignore('Comment this line to run this test')]
|
92
|
+
procedure An_incomplete_game_can_not_be_scored;
|
93
|
+
|
23
94
|
[Test]
|
24
|
-
[Ignore]
|
25
|
-
procedure
|
95
|
+
[Ignore('Comment this line to run this test')]
|
96
|
+
procedure A_game_with_more_than_ten_frames_can_not_be_scored;
|
97
|
+
|
26
98
|
[Test]
|
27
|
-
[Ignore]
|
28
|
-
procedure
|
99
|
+
[Ignore('Comment this line to run this test')]
|
100
|
+
procedure Bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated;
|
101
|
+
|
102
|
+
[Test]
|
103
|
+
[Ignore('Comment this line to run this test')]
|
104
|
+
procedure Both_bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated;
|
105
|
+
|
29
106
|
[Test]
|
30
|
-
[Ignore]
|
31
|
-
procedure
|
107
|
+
[Ignore('Comment this line to run this test')]
|
108
|
+
procedure Bonus_roll_for_a_spare_in_the_last_frame_must_be_rolled_before_score_can_be_calculated;
|
32
109
|
end;
|
33
110
|
|
34
111
|
implementation
|
112
|
+
uses System.SysUtils;
|
35
113
|
|
36
|
-
procedure BowlingTests.
|
114
|
+
procedure BowlingTests.Should_be_able_to_score_a_game_with_all_zeros;
|
37
115
|
var game: IBowlingGame;
|
38
116
|
begin
|
39
|
-
game := NewBowlingGame;
|
40
|
-
|
41
|
-
assert.AreEqual(0,game.Score);
|
117
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
118
|
+
assert.AreEqual(0, game.Score);
|
42
119
|
end;
|
43
120
|
|
44
|
-
procedure BowlingTests.
|
121
|
+
procedure BowlingTests.Should_be_able_to_score_a_game_with_no_strikes_or_spares;
|
45
122
|
var game: IBowlingGame;
|
46
123
|
begin
|
47
|
-
game := NewBowlingGame;
|
48
|
-
|
49
|
-
assert.AreEqual(20,game.Score);
|
124
|
+
game := RollMany([3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6], NewBowlingGame);
|
125
|
+
assert.AreEqual(90, game.Score);
|
50
126
|
end;
|
51
127
|
|
52
|
-
procedure BowlingTests.
|
128
|
+
procedure BowlingTests.A_spare_followed_by_zeros_is_worth_ten_points;
|
53
129
|
var game: IBowlingGame;
|
54
130
|
begin
|
55
|
-
game := NewBowlingGame;
|
56
|
-
|
57
|
-
|
58
|
-
|
131
|
+
game := RollMany([6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
132
|
+
assert.AreEqual(10, game.Score);
|
133
|
+
end;
|
134
|
+
|
135
|
+
procedure BowlingTests.Points_scored_in_the_roll_after_a_spare_are_counted_twice;
|
136
|
+
var game: IBowlingGame;
|
137
|
+
begin
|
138
|
+
game := RollMany([6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
59
139
|
assert.AreEqual(16, game.Score);
|
60
140
|
end;
|
61
141
|
|
62
|
-
procedure BowlingTests.
|
142
|
+
procedure BowlingTests.Consecutive_spares_each_get_a_one_roll_bonus;
|
143
|
+
var game: IBowlingGame;
|
144
|
+
begin
|
145
|
+
game := RollMany([5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
146
|
+
assert.AreEqual(31, game.Score);
|
147
|
+
end;
|
148
|
+
|
149
|
+
procedure BowlingTests.A_spare_in_the_last_frame_gets_a_one_roll_bonus_that_is_counted_once;
|
150
|
+
var game: IBowlingGame;
|
151
|
+
begin
|
152
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7], NewBowlingGame);
|
153
|
+
assert.AreEqual(17, game.Score);
|
154
|
+
end;
|
155
|
+
|
156
|
+
procedure BowlingTests.A_strike_earns_ten_points_in_frame_with_a_single_roll;
|
157
|
+
var game: IBowlingGame;
|
158
|
+
begin
|
159
|
+
game := RollMany([10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
160
|
+
assert.AreEqual(10, game.Score);
|
161
|
+
end;
|
162
|
+
|
163
|
+
procedure BowlingTests.Points_scored_in_the_two_rolls_after_a_strike_are_counted_twice_as_a_bonus;
|
164
|
+
var game: IBowlingGame;
|
165
|
+
begin
|
166
|
+
game := RollMany([10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
167
|
+
assert.AreEqual(26, game.Score);
|
168
|
+
end;
|
169
|
+
|
170
|
+
procedure BowlingTests.Consecutive_strikes_each_get_the_two_roll_bonus;
|
171
|
+
var game: IBowlingGame;
|
172
|
+
begin
|
173
|
+
game := RollMany([10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
174
|
+
assert.AreEqual(81, game.Score);
|
175
|
+
end;
|
176
|
+
|
177
|
+
procedure BowlingTests.A_strike_in_the_last_frame_gets_a_two_roll_bonus_that_is_counted_once;
|
178
|
+
var game: IBowlingGame;
|
179
|
+
begin
|
180
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1], NewBowlingGame);
|
181
|
+
assert.AreEqual(18, game.Score);
|
182
|
+
end;
|
183
|
+
|
184
|
+
procedure BowlingTests.Rolling_a_spare_with_the_two_roll_bonus_does_not_get_a_bonus_roll;
|
185
|
+
var game: IBowlingGame;
|
186
|
+
begin
|
187
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3], NewBowlingGame);
|
188
|
+
assert.AreEqual(20, game.Score);
|
189
|
+
end;
|
190
|
+
|
191
|
+
procedure BowlingTests.Strikes_with_the_two_roll_bonus_do_not_get_bonus_rolls;
|
192
|
+
var game: IBowlingGame;
|
193
|
+
begin
|
194
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10], NewBowlingGame);
|
195
|
+
assert.AreEqual(30, game.Score);
|
196
|
+
end;
|
197
|
+
|
198
|
+
procedure BowlingTests.A_strike_with_the_one_roll_bonus_after_a_spare_in_the_last_frame_does_not_get_a_bonus;
|
199
|
+
var game: IBowlingGame;
|
200
|
+
begin
|
201
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10], NewBowlingGame);
|
202
|
+
assert.AreEqual(20, game.Score);
|
203
|
+
end;
|
204
|
+
|
205
|
+
procedure BowlingTests.All_strikes_is_a_perfect_game;
|
206
|
+
var game: IBowlingGame;
|
207
|
+
begin
|
208
|
+
game := RollMany([10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], NewBowlingGame);
|
209
|
+
assert.AreEqual(300, game.Score);
|
210
|
+
end;
|
211
|
+
|
212
|
+
procedure BowlingTests.Rolls_can_not_score_negative_points;
|
213
|
+
var game: IBowlingGame;
|
214
|
+
begin
|
215
|
+
game := RollMany([-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
216
|
+
Assert.AreEqual(-1, game.Score);
|
217
|
+
end;
|
218
|
+
|
219
|
+
procedure BowlingTests.A_roll_can_not_score_more_than_10_points;
|
220
|
+
var game: IBowlingGame;
|
221
|
+
begin
|
222
|
+
game := RollMany([11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
223
|
+
Assert.AreEqual(-1, game.Score);
|
224
|
+
end;
|
225
|
+
|
226
|
+
procedure BowlingTests.Two_rolls_in_a_frame_can_not_score_more_than_10_points;
|
227
|
+
var game: IBowlingGame;
|
228
|
+
begin
|
229
|
+
game := RollMany([5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
230
|
+
Assert.AreEqual(-1, game.Score);
|
231
|
+
end;
|
232
|
+
|
233
|
+
procedure BowlingTests.Two_bonus_rolls_after_a_strike_in_the_last_frame_can_not_score_more_than_10_points;
|
63
234
|
var game: IBowlingGame;
|
64
235
|
begin
|
65
|
-
game := NewBowlingGame;
|
66
|
-
|
67
|
-
game.Roll(3);
|
68
|
-
game.Roll(4);
|
69
|
-
RollMany(0, 16, game);
|
70
|
-
assert.AreEqual(24, game.Score);
|
236
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6], NewBowlingGame);
|
237
|
+
Assert.AreEqual(-1, game.Score);
|
71
238
|
end;
|
72
239
|
|
73
|
-
procedure BowlingTests.
|
240
|
+
procedure BowlingTests.An_unstarted_game_can_not_be_scored;
|
74
241
|
var game: IBowlingGame;
|
75
242
|
begin
|
76
|
-
game := NewBowlingGame;
|
77
|
-
|
78
|
-
assert.AreEqual(300, Game.Score);
|
243
|
+
game := RollMany([],NewBowlingGame);
|
244
|
+
Assert.AreEqual(-1, game.Score);
|
79
245
|
end;
|
80
246
|
|
81
|
-
|
82
|
-
var
|
247
|
+
procedure BowlingTests.An_incomplete_game_can_not_be_scored;
|
248
|
+
var game: IBowlingGame;
|
249
|
+
begin
|
250
|
+
game := RollMany([0, 0], NewBowlingGame);
|
251
|
+
Assert.AreEqual(-1, game.Score);
|
252
|
+
end;
|
253
|
+
|
254
|
+
procedure BowlingTests.A_game_with_more_than_ten_frames_can_not_be_scored;
|
255
|
+
var game: IBowlingGame;
|
256
|
+
begin
|
257
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], NewBowlingGame);
|
258
|
+
Assert.AreEqual(-1, game.Score);
|
259
|
+
end;
|
260
|
+
|
261
|
+
procedure BowlingTests.Bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated;
|
262
|
+
var game: IBowlingGame;
|
83
263
|
begin
|
84
|
-
|
85
|
-
|
264
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10], NewBowlingGame);
|
265
|
+
Assert.AreEqual(-1, game.Score);
|
86
266
|
end;
|
87
267
|
|
88
|
-
|
268
|
+
procedure BowlingTests.Both_bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated;
|
269
|
+
var game: IBowlingGame;
|
270
|
+
begin
|
271
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10], NewBowlingGame);
|
272
|
+
Assert.AreEqual(-1, game.Score);
|
273
|
+
end;
|
274
|
+
|
275
|
+
procedure BowlingTests.Bonus_roll_for_a_spare_in_the_last_frame_must_be_rolled_before_score_can_be_calculated;
|
276
|
+
var game: IBowlingGame;
|
89
277
|
begin
|
90
|
-
game
|
91
|
-
game.
|
278
|
+
game := RollMany([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3], NewBowlingGame);
|
279
|
+
Assert.AreEqual(-1, game.Score);
|
92
280
|
end;
|
93
281
|
|
94
|
-
class
|
282
|
+
class function BowlingTests.RollMany(pins: array of integer; game: IBowlingGame): IBowlingGame;
|
283
|
+
var count: integer;
|
95
284
|
begin
|
96
|
-
|
285
|
+
for count in pins do
|
286
|
+
game.Roll(count);
|
287
|
+
result := game;
|
97
288
|
end;
|
98
289
|
|
99
290
|
initialization
|
@@ -10,25 +10,25 @@ import (
|
|
10
10
|
|
11
11
|
type operatorFn func(stack *[]int) error
|
12
12
|
|
13
|
-
type
|
13
|
+
type operatorID byte
|
14
14
|
|
15
15
|
const (
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
opAdd operatorID = iota
|
17
|
+
opSub
|
18
|
+
opMul
|
19
|
+
opDiv
|
20
|
+
opDrop
|
21
|
+
opDup
|
22
|
+
opSwap
|
23
|
+
opOver
|
24
|
+
opConst
|
25
|
+
opUserDef
|
26
|
+
opEndDef
|
27
27
|
)
|
28
28
|
|
29
29
|
type operatorTyp struct {
|
30
30
|
fn operatorFn
|
31
|
-
id
|
31
|
+
id operatorID
|
32
32
|
}
|
33
33
|
|
34
34
|
func Forth(input []string) (result []int, err error) {
|
@@ -73,15 +73,15 @@ func parse(phrase string, userDefs map[string][]operatorTyp) (oplist []operatorT
|
|
73
73
|
if udef, ok := userDefs[w]; ok {
|
74
74
|
oplist = append(oplist, udef...)
|
75
75
|
} else if op, ok := builtinOps[w]; ok {
|
76
|
-
if op.id ==
|
76
|
+
if op.id == opUserDef {
|
77
77
|
// Handle user defined word definition.
|
78
78
|
t++
|
79
79
|
if t >= len(words)-2 {
|
80
|
-
return nil,
|
80
|
+
return nil, errEmptyUserDef
|
81
81
|
}
|
82
82
|
userword := strings.ToUpper(words[t])
|
83
83
|
if _, numerr := strconv.Atoi(userword); numerr == nil {
|
84
|
-
return nil,
|
84
|
+
return nil, errInvalidUserDef
|
85
85
|
}
|
86
86
|
t++
|
87
87
|
var userops []operatorTyp
|
@@ -90,17 +90,16 @@ func parse(phrase string, userDefs map[string][]operatorTyp) (oplist []operatorT
|
|
90
90
|
if err != nil {
|
91
91
|
return nil, err
|
92
92
|
}
|
93
|
-
if oneOp[0].id ==
|
93
|
+
if oneOp[0].id == opEndDef {
|
94
94
|
break
|
95
95
|
}
|
96
96
|
userops = append(userops, oneOp...)
|
97
97
|
t++
|
98
98
|
}
|
99
99
|
if len(userops) == 0 {
|
100
|
-
return nil,
|
101
|
-
} else {
|
102
|
-
userDefs[userword] = userops
|
100
|
+
return nil, errEmptyUserDef
|
103
101
|
}
|
102
|
+
userDefs[userword] = userops
|
104
103
|
} else {
|
105
104
|
// Normal builtin operator.
|
106
105
|
oplist = append(oplist, op)
|
@@ -113,7 +112,7 @@ func parse(phrase string, userDefs map[string][]operatorTyp) (oplist []operatorT
|
|
113
112
|
return nil, err
|
114
113
|
}
|
115
114
|
oplist = append(oplist,
|
116
|
-
operatorTyp{id:
|
115
|
+
operatorTyp{id: opConst,
|
117
116
|
fn: func(stack *[]int) error {
|
118
117
|
push(stack, x)
|
119
118
|
return nil
|
@@ -126,16 +125,16 @@ func parse(phrase string, userDefs map[string][]operatorTyp) (oplist []operatorT
|
|
126
125
|
|
127
126
|
// builtinOps are the pre-defined operators to support.
|
128
127
|
var builtinOps = map[string]operatorTyp{
|
129
|
-
"+": {add,
|
130
|
-
"-": {subtract,
|
131
|
-
"*": {multiply,
|
132
|
-
"/": {divide,
|
133
|
-
"DUP": {dup,
|
134
|
-
"DROP": {drop,
|
135
|
-
"SWAP": {swap,
|
136
|
-
"OVER": {over,
|
137
|
-
":": {nil,
|
138
|
-
";": {nil,
|
128
|
+
"+": {add, opAdd},
|
129
|
+
"-": {subtract, opSub},
|
130
|
+
"*": {multiply, opMul},
|
131
|
+
"/": {divide, opDiv},
|
132
|
+
"DUP": {dup, opDrop},
|
133
|
+
"DROP": {drop, opDup},
|
134
|
+
"SWAP": {swap, opSwap},
|
135
|
+
"OVER": {over, opOver},
|
136
|
+
":": {nil, opUserDef},
|
137
|
+
";": {nil, opEndDef},
|
139
138
|
}
|
140
139
|
|
141
140
|
func pop(stack *[]int) (v int, err error) {
|
@@ -145,7 +144,7 @@ func pop(stack *[]int) (v int, err error) {
|
|
145
144
|
*stack = (*stack)[:slen-1]
|
146
145
|
return v, nil
|
147
146
|
}
|
148
|
-
return 0,
|
147
|
+
return 0, errNotEnoughOperands
|
149
148
|
}
|
150
149
|
|
151
150
|
func pop2(stack *[]int) (v1, v2 int, err error) {
|
@@ -188,7 +187,7 @@ func divide(stack *[]int) error {
|
|
188
187
|
return err
|
189
188
|
}
|
190
189
|
if v1 == 0 {
|
191
|
-
return
|
190
|
+
return errDivideByZero
|
192
191
|
}
|
193
192
|
push(stack, v2/v1)
|
194
193
|
return nil
|
@@ -230,9 +229,9 @@ func swap(stack *[]int) error {
|
|
230
229
|
return nil
|
231
230
|
}
|
232
231
|
|
233
|
-
var
|
234
|
-
var
|
235
|
-
var
|
236
|
-
var
|
232
|
+
var errNotEnoughOperands = errors.New("not enough operands")
|
233
|
+
var errDivideByZero = errors.New("attempt to divide by zero")
|
234
|
+
var errEmptyUserDef = errors.New("empty user definition")
|
235
|
+
var errInvalidUserDef = errors.New("invalid user def word")
|
237
236
|
|
238
237
|
const testVersion = 1
|
@@ -140,7 +140,7 @@ func TestGarden(t *testing.T) {
|
|
140
140
|
t.Fatalf("Garden %d lookup %s returned ok = %t, want %t.",
|
141
141
|
test.number, l.child, ok, l.ok)
|
142
142
|
case ok && !reflect.DeepEqual(plants, l.plants):
|
143
|
-
t.Fatalf("Garden %d lookup %s = %
|
143
|
+
t.Fatalf("Garden %d lookup %s = %q, want %q.",
|
144
144
|
test.number, l.child, plants, l.plants)
|
145
145
|
}
|
146
146
|
}
|
@@ -192,7 +192,7 @@ RVGCCGCV`
|
|
192
192
|
t.Skip("Garden %d lookup %s returned ok = false, want true.",
|
193
193
|
n, child)
|
194
194
|
case !reflect.DeepEqual(plants, expPlants):
|
195
|
-
t.Fatalf("Garden %d lookup %s = %
|
195
|
+
t.Fatalf("Garden %d lookup %s = %q, want %q.",
|
196
196
|
n, child, plants, expPlants)
|
197
197
|
}
|
198
198
|
}
|
@@ -90,6 +90,8 @@ public class AllergiesTest {
|
|
90
90
|
Allergies allergies = new Allergies(5);
|
91
91
|
|
92
92
|
assertEquals(true, allergies.isAllergicTo(Allergen.EGGS));
|
93
|
+
assertEquals(true, allergies.isAllergicTo(Allergen.SHELLFISH));
|
94
|
+
assertEquals(false, allergies.isAllergicTo(Allergen.STRAWBERRIES));
|
93
95
|
}
|
94
96
|
|
95
97
|
@Ignore
|
data/tracks/scala/config.json
CHANGED
@@ -0,0 +1,95 @@
|
|
1
|
+
class Node[+T]
|
2
|
+
case object Empty extends Node[Nothing]
|
3
|
+
case class NonEmpty[T](value: T, next: Node[T]) extends Node[T]
|
4
|
+
|
5
|
+
trait SimpleLinkedList[T] {
|
6
|
+
def isEmpty: Boolean
|
7
|
+
def value: T
|
8
|
+
def add(item: T): SimpleLinkedList[T]
|
9
|
+
def next: SimpleLinkedList[T]
|
10
|
+
def reverse: SimpleLinkedList[T]
|
11
|
+
def toSeq: Seq[T]
|
12
|
+
}
|
13
|
+
|
14
|
+
class SimpleLinkedListImpl[T](first: Node[T]) extends SimpleLinkedList[T] {
|
15
|
+
|
16
|
+
def isEmpty: Boolean = first == Empty
|
17
|
+
|
18
|
+
def value: T = first match {
|
19
|
+
case Empty => throw new NoSuchElementException
|
20
|
+
case node: NonEmpty[T] => node.value
|
21
|
+
}
|
22
|
+
|
23
|
+
def add(item: T): SimpleLinkedList[T] = {
|
24
|
+
var reversed = reverse
|
25
|
+
var current = NonEmpty[T](item, Empty)
|
26
|
+
|
27
|
+
while (!reversed.isEmpty) {
|
28
|
+
val value = reversed.value
|
29
|
+
val newNode = NonEmpty[T](value, current)
|
30
|
+
|
31
|
+
current = newNode
|
32
|
+
reversed = reversed.next
|
33
|
+
}
|
34
|
+
|
35
|
+
new SimpleLinkedListImpl[T](current)
|
36
|
+
}
|
37
|
+
|
38
|
+
def next: SimpleLinkedList[T] = first match {
|
39
|
+
case Empty => this
|
40
|
+
case node: NonEmpty[T] => new SimpleLinkedListImpl[T](first.asInstanceOf[NonEmpty[T]].next)
|
41
|
+
}
|
42
|
+
|
43
|
+
def reverse: SimpleLinkedList[T] = {
|
44
|
+
var newLast: Node[T] = Empty
|
45
|
+
var prev: Node[T] = Empty
|
46
|
+
var current = first
|
47
|
+
var next: Node[T] = Empty
|
48
|
+
while (current != Empty) {
|
49
|
+
val newNode = NonEmpty[T](current.asInstanceOf[NonEmpty[T]].value, prev)
|
50
|
+
|
51
|
+
if (newLast == Empty) {
|
52
|
+
newLast = newNode
|
53
|
+
}
|
54
|
+
|
55
|
+
next = current.asInstanceOf[NonEmpty[T]].next
|
56
|
+
prev = newNode
|
57
|
+
current = next
|
58
|
+
}
|
59
|
+
|
60
|
+
new SimpleLinkedListImpl[T](prev)
|
61
|
+
}
|
62
|
+
|
63
|
+
def length: Int = {
|
64
|
+
var len = 0
|
65
|
+
|
66
|
+
var current = first
|
67
|
+
while (current != Empty) {
|
68
|
+
len = len + 1
|
69
|
+
current = current.asInstanceOf[NonEmpty[T]].next
|
70
|
+
}
|
71
|
+
|
72
|
+
len
|
73
|
+
}
|
74
|
+
|
75
|
+
def toSeq: Seq[T] = {
|
76
|
+
var xs = List[T]()
|
77
|
+
|
78
|
+
var current = first
|
79
|
+
while (current != Empty) {
|
80
|
+
xs = current.asInstanceOf[NonEmpty[T]].value :: xs
|
81
|
+
current = current.asInstanceOf[NonEmpty[T]].next
|
82
|
+
}
|
83
|
+
|
84
|
+
xs.reverse
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
object SimpleLinkedList {
|
89
|
+
def apply[T](): SimpleLinkedList[T] = new SimpleLinkedListImpl[T](Empty)
|
90
|
+
|
91
|
+
def apply[T](ts: T*): SimpleLinkedList[T] = fromSeq(ts)
|
92
|
+
|
93
|
+
def fromSeq[T](seq: Seq[T]): SimpleLinkedList[T] =
|
94
|
+
seq.foldLeft(SimpleLinkedList[T]())((acc, t) => acc.add(t))
|
95
|
+
}
|
@@ -0,0 +1,108 @@
|
|
1
|
+
import org.scalacheck.{Arbitrary}
|
2
|
+
import org.scalatest.prop.GeneratorDrivenPropertyChecks
|
3
|
+
import org.scalatest.{FlatSpec, Matchers}
|
4
|
+
|
5
|
+
|
6
|
+
class SimpleLinkedListTest extends FlatSpec with Matchers with GeneratorDrivenPropertyChecks {
|
7
|
+
|
8
|
+
private implicit def arbitrarySimpleLinkedList[T](implicit arbitraryTs: Arbitrary[Array[T]]): Arbitrary[SimpleLinkedList[T]] =
|
9
|
+
Arbitrary {
|
10
|
+
arbitraryTs.arbitrary map (SimpleLinkedList(_:_*))
|
11
|
+
}
|
12
|
+
|
13
|
+
it should "handle single item list" in {
|
14
|
+
val list = SimpleLinkedList().add(1)
|
15
|
+
list.isEmpty should be (false)
|
16
|
+
list.value should be (1)
|
17
|
+
}
|
18
|
+
|
19
|
+
it should "handle single item has no next item" in {
|
20
|
+
pending
|
21
|
+
val list = SimpleLinkedList().add(1)
|
22
|
+
list.next.isEmpty should be (true)
|
23
|
+
}
|
24
|
+
|
25
|
+
it should "handle two item list" in {
|
26
|
+
pending
|
27
|
+
val list = SimpleLinkedList().add(1).add(2)
|
28
|
+
list.value should be (1)
|
29
|
+
list.next.value should be (2)
|
30
|
+
}
|
31
|
+
|
32
|
+
it should "handle two item list has no next value" in {
|
33
|
+
pending
|
34
|
+
val list = SimpleLinkedList().add(1).add(2)
|
35
|
+
list.next.next.isEmpty should be (true)
|
36
|
+
}
|
37
|
+
|
38
|
+
it should "allow creation from a Seq" in {
|
39
|
+
pending
|
40
|
+
val list = SimpleLinkedList.fromSeq(List(3, 2, 1))
|
41
|
+
list.value should be (3)
|
42
|
+
list.next.value should be (2)
|
43
|
+
list.next.next.value should be (1)
|
44
|
+
}
|
45
|
+
|
46
|
+
it should "allow conversion to a Seq" in {
|
47
|
+
pending
|
48
|
+
val list = SimpleLinkedList.fromSeq(List(3, 2, 1))
|
49
|
+
val seq = list.toSeq
|
50
|
+
seq should be (List(3, 2, 1))
|
51
|
+
}
|
52
|
+
|
53
|
+
it should "handle reverse" in {
|
54
|
+
pending
|
55
|
+
val list = SimpleLinkedList.fromSeq(List(1, 2, 3, 4, 5, 6))
|
56
|
+
val reversed = list.reverse
|
57
|
+
reversed.value should be (6)
|
58
|
+
reversed.next.value should be (5)
|
59
|
+
reversed.next.next.value should be (4)
|
60
|
+
reversed.next.next.next.value should be (3)
|
61
|
+
reversed.next.next.next.next.value should be (2)
|
62
|
+
reversed.next.next.next.next.next.value should be (1)
|
63
|
+
}
|
64
|
+
|
65
|
+
it should "handle arbitrary list fromSeq toSeq" in {
|
66
|
+
pending
|
67
|
+
forAll { seq: Seq[Int] =>
|
68
|
+
assert(SimpleLinkedList.fromSeq(seq).toSeq == seq)
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
it should "handle reverse arbitrary list " in {
|
73
|
+
pending
|
74
|
+
forAll { seq: Seq[Int] =>
|
75
|
+
assert(SimpleLinkedList.fromSeq(seq).reverse.toSeq == seq.reverse)
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
it should "reverse arbitrary list back to original" in {
|
80
|
+
pending
|
81
|
+
forAll { list: SimpleLinkedList[Int] =>
|
82
|
+
assert(list.reverse.reverse.toSeq == list.toSeq)
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
it should "return correct arbitrary value at index" in {
|
87
|
+
pending
|
88
|
+
def nthDatum(list: SimpleLinkedList[Int], i: Int): Int = {
|
89
|
+
(0 until i).foldLeft(list)((acc, j) => acc.next).value
|
90
|
+
}
|
91
|
+
|
92
|
+
forAll { xs: Seq[Int] =>
|
93
|
+
whenever(xs.nonEmpty) {
|
94
|
+
val list = SimpleLinkedList.fromSeq(xs)
|
95
|
+
xs.indices.foreach {
|
96
|
+
i => assert(nthDatum(list, i) == xs(i))
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
it should "handle arbitrary generics" in {
|
103
|
+
pending
|
104
|
+
forAll { xs: Seq[String] =>
|
105
|
+
assert(SimpleLinkedList.fromSeq(xs).toSeq == xs)
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
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.8.
|
4
|
+
version: 2.0.8.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katrina Owen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -7391,6 +7391,10 @@ files:
|
|
7391
7391
|
- tracks/scala/exercises/simple-cipher/example.scala
|
7392
7392
|
- tracks/scala/exercises/simple-cipher/src/main/scala/.keep
|
7393
7393
|
- tracks/scala/exercises/simple-cipher/src/test/scala/CipherTest.scala
|
7394
|
+
- tracks/scala/exercises/simple-linked-list/build.sbt
|
7395
|
+
- tracks/scala/exercises/simple-linked-list/example.scala
|
7396
|
+
- tracks/scala/exercises/simple-linked-list/src/main/scala/SimpleLinkedList.scala
|
7397
|
+
- tracks/scala/exercises/simple-linked-list/src/test/scala/SimpleLinkedListTest.scala
|
7394
7398
|
- tracks/scala/exercises/space-age/build.sbt
|
7395
7399
|
- tracks/scala/exercises/space-age/example.scala
|
7396
7400
|
- tracks/scala/exercises/space-age/src/main/scala/.keep
|