trackler 2.0.8.18 → 2.0.8.19

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.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/common/.gitignore +1 -0
  3. data/common/.travis.yml +5 -8
  4. data/common/README.md +18 -5
  5. data/common/exercises/grep/canonical-data.json +290 -269
  6. data/common/exercises/phone-number/canonical-data.json +2 -2
  7. data/common/exercises/pov/canonical-data.json +2 -5
  8. data/common/exercises/roman-numerals/canonical-data.json +112 -74
  9. data/common/exercises/tournament/canonical-data.json +86 -85
  10. data/common/exercises/two-bucket/canonical-data.json +55 -47
  11. data/common/package.json +16 -0
  12. data/common/yarn.lock +195 -0
  13. data/lib/trackler/version.rb +1 -1
  14. data/tracks/c/docs/LEARNING.md +1 -1
  15. data/tracks/c/exercises/space-age/src/example.c +15 -47
  16. data/tracks/c/exercises/space-age/src/example.h +12 -8
  17. data/tracks/c/exercises/space-age/test/test_space_age.c +8 -8
  18. data/tracks/ceylon/docs/TESTS.md +5 -2
  19. data/tracks/ceylon/exercises/TRACK_HINTS.md +5 -2
  20. data/tracks/csharp/.gitignore +0 -4
  21. data/tracks/csharp/.travis.yml +9 -20
  22. data/tracks/csharp/appveyor.yml +2 -4
  23. data/tracks/csharp/build.cake +95 -0
  24. data/tracks/csharp/build.ps1 +189 -0
  25. data/tracks/csharp/build.sh +99 -31
  26. data/tracks/csharp/circle.yml +3 -12
  27. data/tracks/delphi/config.json +8 -0
  28. data/tracks/delphi/exercises/minesweeper/MineSweeper.dpr +60 -0
  29. data/tracks/delphi/exercises/minesweeper/uMineSweeperExample.pas +70 -0
  30. data/tracks/delphi/exercises/minesweeper/uMineSweeperTest.pas +270 -0
  31. data/tracks/dlang/config.json +86 -31
  32. data/tracks/elixir/config.json +7 -0
  33. data/tracks/elixir/exercises/rotational-cipher/example.exs +35 -0
  34. data/tracks/elixir/exercises/rotational-cipher/rotational_cipher.exs +13 -0
  35. data/tracks/elixir/exercises/rotational-cipher/rotational_cipher_test.exs +80 -0
  36. data/tracks/go/exercises/raindrops/raindrops_test.go +4 -1
  37. data/tracks/go/exercises/react/react_test.go +6 -8
  38. data/tracks/go/exercises/rna-transcription/rna_transcription_test.go +4 -1
  39. data/tracks/go/exercises/robot-simulator/robot_simulator_test.go +5 -2
  40. data/tracks/haskell/exercises/allergies/src/Allergies.hs +2 -2
  41. data/tracks/haskell/exercises/atbash-cipher/src/Atbash.hs +2 -2
  42. data/tracks/haskell/exercises/bank-account/src/BankAccount.hs +3 -3
  43. data/tracks/haskell/exercises/binary-search-tree/src/BST.hs +7 -7
  44. data/tracks/haskell/exercises/bowling/src/Bowling.hs +1 -1
  45. data/tracks/haskell/exercises/clock/src/Clock.hs +4 -4
  46. data/tracks/haskell/exercises/connect/src/Connect.hs +1 -1
  47. data/tracks/haskell/exercises/crypto-square/src/CryptoSquare.hs +1 -1
  48. data/tracks/haskell/exercises/custom-set/src/CustomSet.hs +12 -12
  49. data/tracks/haskell/exercises/difference-of-squares/src/Squares.hs +3 -3
  50. data/tracks/haskell/exercises/etl/src/ETL.hs +1 -1
  51. data/tracks/haskell/exercises/forth/src/Forth.hs +2 -2
  52. data/tracks/haskell/exercises/go-counting/src/Counting.hs +2 -2
  53. data/tracks/haskell/exercises/kindergarten-garden/src/Garden.hs +3 -3
  54. data/tracks/haskell/exercises/largest-series-product/src/Series.hs +1 -1
  55. data/tracks/haskell/exercises/lens-person/src/Person.hs +4 -4
  56. data/tracks/julia/.travis.yml +3 -2
  57. data/tracks/ocaml/exercises/all-your-base/test.ml +2 -2
  58. data/tracks/ocaml/exercises/beer-song/test.ml +25 -24
  59. data/tracks/ocaml/exercises/phone-number/test.ml +22 -22
  60. data/tracks/ocaml/exercises/run-length-encoding/test.ml +5 -5
  61. data/tracks/ocaml/exercises/word-count/test.ml +1 -1
  62. data/tracks/ocaml/tools/test-generator/templates/beer-song/template.ml +20 -1
  63. data/tracks/purescript/config.json +7 -0
  64. data/tracks/purescript/exercises/word-count/bower.json +17 -0
  65. data/tracks/purescript/exercises/word-count/examples/src/WordCount.purs +31 -0
  66. data/tracks/purescript/exercises/word-count/src/WordCount.purs +3 -0
  67. data/tracks/purescript/exercises/word-count/test/Main.purs +89 -0
  68. data/tracks/python/exercises/accumulate/accumulate.py +2 -0
  69. data/tracks/python/exercises/acronym/acronym.py +2 -0
  70. data/tracks/python/exercises/allergies/allergies.py +3 -0
  71. data/tracks/python/exercises/allergies/example.py +1 -1
  72. data/tracks/python/exercises/anagram/anagram.py +2 -0
  73. data/tracks/python/exercises/atbash-cipher/atbash_cipher.py +6 -0
  74. data/tracks/python/exercises/beer-song/beer_song.py +6 -0
  75. data/tracks/python/exercises/binary-search/binary_search.py +2 -0
  76. data/tracks/python/exercises/binary/binary.py +2 -0
  77. data/tracks/python/exercises/bob/bob.py +2 -8
  78. data/tracks/python/exercises/bracket-push/bracket_push.py +2 -0
  79. data/tracks/python/exercises/circular-buffer/circular_buffer.py +11 -0
  80. data/tracks/python/exercises/clock/clock.py +3 -0
  81. data/tracks/python/exercises/clock/example.py +1 -1
  82. data/tracks/python/exercises/crypto-square/crypto_square.py +2 -0
  83. data/tracks/python/exercises/diamond/diamond.py +2 -0
  84. data/tracks/python/exercises/difference-of-squares/difference_of_squares.py +10 -0
  85. data/tracks/python/exercises/etl/etl.py +2 -0
  86. data/tracks/python/exercises/flatten-array/flatten_array.py +2 -0
  87. data/tracks/python/exercises/gigasecond/gigasecond.py +2 -0
  88. data/tracks/python/exercises/grade-school/grade_school.py +3 -0
  89. data/tracks/python/exercises/grains/grains.py +6 -0
  90. data/tracks/python/exercises/hamming/hamming.py +2 -0
  91. data/tracks/python/exercises/hello-world/hello_world.py +2 -7
  92. data/tracks/python/exercises/hexadecimal/hexadecimal.py +2 -0
  93. data/tracks/python/exercises/house/house.py +6 -0
  94. data/tracks/python/exercises/kindergarten-garden/kindergarten_garden.py +3 -0
  95. data/tracks/python/exercises/largest-series-product/largest_series_product.py +2 -0
  96. data/tracks/python/exercises/leap/leap.py +2 -0
  97. data/tracks/python/exercises/linked-list/linked_list.py +2 -8
  98. data/tracks/python/exercises/list-ops/list_ops.py +18 -22
  99. data/tracks/python/exercises/luhn/luhn.py +3 -0
  100. data/tracks/python/exercises/matrix/matrix.py +3 -0
  101. data/tracks/python/exercises/meetup/meetup.py +2 -0
  102. data/tracks/python/exercises/minesweeper/minesweeper.py +2 -0
  103. data/tracks/python/exercises/nth-prime/nth_prime.py +2 -0
  104. data/tracks/python/exercises/nucleotide-count/nucleotide_count.py +6 -0
  105. data/tracks/python/exercises/ocr-numbers/ocr_numbers.py +6 -0
  106. data/tracks/python/exercises/ocr-numbers/{ocr_test.py → ocr_numbers_test.py} +0 -0
  107. data/tracks/python/exercises/octal/octal.py +2 -0
  108. data/tracks/python/exercises/palindrome-products/palindrome_products.py +6 -0
  109. data/tracks/python/exercises/pangram/pangram.py +2 -0
  110. data/tracks/python/exercises/pascals-triangle/pascals_triangle.py +10 -0
  111. data/tracks/python/exercises/perfect-numbers/perfect_numbers.py +6 -0
  112. data/tracks/python/exercises/phone-number/phone_number.py +3 -0
  113. data/tracks/python/exercises/pig-latin/pig_latin.py +2 -0
  114. data/tracks/python/exercises/point-mutations/point_mutations.py +2 -0
  115. data/tracks/python/exercises/poker/poker.py +2 -0
  116. data/tracks/python/exercises/prime-factors/prime_factors.py +2 -0
  117. data/tracks/python/exercises/proverb/proverb.py +2 -0
  118. data/tracks/python/exercises/pythagorean-triplet/pythagorean_triplet.py +10 -0
  119. data/tracks/python/exercises/queen-attack/queen_attack.py +6 -0
  120. data/tracks/python/exercises/rail-fence-cipher/rail_fence_cipher.py +10 -0
  121. data/tracks/python/exercises/raindrops/raindrops.py +2 -0
  122. data/tracks/python/exercises/rectangles/example.py +1 -1
  123. data/tracks/python/exercises/rectangles/rectangles.py +2 -0
  124. data/tracks/python/exercises/rectangles/{rectangles_count_test.py → rectangles_test.py} +0 -0
  125. data/tracks/python/exercises/rna-transcription/rna_transcription.py +2 -0
  126. data/tracks/python/exercises/robot-name/robot_name.py +3 -0
  127. data/tracks/python/exercises/robot-simulator/robot_simulator.py +3 -0
  128. data/tracks/python/exercises/roman-numerals/roman_numerals.py +2 -0
  129. data/tracks/python/exercises/run-length-encoding/run_length_encoding.py +6 -0
  130. data/tracks/python/exercises/run-length-encoding/{run_length_test.py → run_length_encoding_test.py} +1 -1
  131. data/tracks/python/exercises/saddle-points/saddle_points.py +2 -0
  132. data/tracks/python/exercises/say/example.py +1 -1
  133. data/tracks/python/exercises/say/say.py +2 -0
  134. data/tracks/python/exercises/say/say_test.py +3 -0
  135. data/tracks/python/exercises/scrabble-score/scrabble_score.py +2 -0
  136. data/tracks/python/exercises/secret-handshake/secret_handshake.py +6 -0
  137. data/tracks/python/exercises/secret-handshake/{handshake_test.py → secret_handshake_test.py} +0 -0
  138. data/tracks/python/exercises/series/series.py +2 -0
  139. data/tracks/python/exercises/sieve/sieve.py +2 -0
  140. data/tracks/python/exercises/simple-cipher/example.py +1 -1
  141. data/tracks/python/exercises/simple-cipher/simple_cipher.py +8 -0
  142. data/tracks/python/exercises/space-age/space_age.py +3 -0
  143. data/tracks/python/exercises/strain/strain.py +6 -0
  144. data/tracks/python/exercises/sublist/sublist.py +2 -0
  145. data/tracks/python/exercises/sum-of-multiples/sum_of_multiples.py +2 -0
  146. data/tracks/python/exercises/triangle/triangle.py +7 -0
  147. data/tracks/python/exercises/trinary/trinary.py +2 -0
  148. data/tracks/python/exercises/twelve-days/twelve_days.py +10 -0
  149. data/tracks/python/exercises/word-count/word_count.py +2 -0
  150. data/tracks/python/exercises/wordy/wordy.py +2 -0
  151. data/tracks/python/exercises/zebra-puzzle/zebra_puzzle.py +2 -0
  152. data/tracks/ruby/exercises/beer-song/.meta/.version +1 -0
  153. data/tracks/ruby/exercises/beer-song/beer_song_test.rb +62 -36
  154. data/tracks/ruby/exercises/beer-song/example.rb +1 -5
  155. data/tracks/ruby/exercises/beer-song/example.tt +22 -0
  156. data/tracks/ruby/lib/beer_song_cases.rb +43 -0
  157. data/tracks/swift/exercises/matrix/Tests/MatrixTests/MatrixTests.swift +1 -1
  158. metadata +94 -13
  159. data/common/bin/jsonlint +0 -27
  160. data/tracks/csharp/.paket/paket.bootstrapper.exe +0 -0
  161. data/tracks/csharp/Zipper.cs +0 -137
  162. data/tracks/csharp/build.cmd +0 -14
  163. data/tracks/csharp/build.fsx +0 -78
  164. data/tracks/csharp/paket.dependencies +0 -2
  165. data/tracks/csharp/paket.lock +0 -3
@@ -156,6 +156,14 @@
156
156
  "Classes"
157
157
  ]
158
158
  },
159
+ {
160
+ "slug": "minesweeper",
161
+ "difficulty": 5,
162
+ "topics": [
163
+ "Parsing",
164
+ "Transforming"
165
+ ]
166
+ },
159
167
  {
160
168
  "slug": "bowling",
161
169
  "difficulty": 6,
@@ -0,0 +1,60 @@
1
+ program MineSweeper;
2
+
3
+ {$IFNDEF TESTINSIGHT}
4
+ {$APPTYPE CONSOLE}
5
+ {$ENDIF}{$STRONGLINKTYPES ON}
6
+ uses
7
+ System.SysUtils,
8
+ {$IFDEF TESTINSIGHT}
9
+ TestInsight.DUnitX,
10
+ {$ENDIF }
11
+ DUnitX.Loggers.Console,
12
+ DUnitX.Loggers.Xml.NUnit,
13
+ DUnitX.TestFramework,
14
+ uMineSweeperTest in 'uMineSweeperTest.pas',
15
+ uMineSweeper in 'uMineSweeper.pas';
16
+
17
+ var
18
+ runner : ITestRunner;
19
+ results : IRunResults;
20
+ logger : ITestLogger;
21
+ nunitLogger : ITestLogger;
22
+ begin
23
+ {$IFDEF TESTINSIGHT}
24
+ TestInsight.DUnitX.RunRegisteredTests;
25
+ exit;
26
+ {$ENDIF}
27
+ try
28
+ //Check command line options, will exit if invalid
29
+ TDUnitX.CheckCommandLine;
30
+ //Create the test runner
31
+ runner := TDUnitX.CreateRunner;
32
+ //Tell the runner to use RTTI to find Fixtures
33
+ runner.UseRTTI := True;
34
+ //tell the runner how we will log things
35
+ //Log to the console window
36
+ logger := TDUnitXConsoleLogger.Create(true);
37
+ runner.AddLogger(logger);
38
+ //Generate an NUnit compatible XML File
39
+ nunitLogger := TDUnitXXMLNUnitFileLogger.Create(TDUnitX.Options.XMLOutputFile);
40
+ runner.AddLogger(nunitLogger);
41
+ runner.FailsOnNoAsserts := False; //When true, Assertions must be made during tests;
42
+
43
+ //Run tests
44
+ results := runner.Execute;
45
+ if not results.AllPassed then
46
+ System.ExitCode := EXIT_ERRORS;
47
+
48
+ {$IFNDEF CI}
49
+ //We don't want this happening when running under CI.
50
+ if TDUnitX.Options.ExitBehavior = TDUnitXExitBehavior.Pause then
51
+ begin
52
+ System.Write('Done.. press <Enter> key to quit.');
53
+ System.Readln;
54
+ end;
55
+ {$ENDIF}
56
+ except
57
+ on E: Exception do
58
+ System.Writeln(E.ClassName, ': ', E.Message);
59
+ end;
60
+ end.
@@ -0,0 +1,70 @@
1
+ unit uMineSweeper;
2
+
3
+ interface
4
+
5
+ type
6
+ TMineSweeper = class
7
+ private
8
+ class function GetCountForSquare(board: array of string; x, y: integer): integer; static;
9
+ public
10
+ class function Annotate(aInput: string): string; static;
11
+ end;
12
+
13
+ implementation
14
+ uses System.Generics.Collections, System.StrUtils, System.SysUtils;
15
+
16
+ class function TMineSweeper.Annotate(aInput: string): string;
17
+ var lResults: TList<string>;
18
+ Board: TArray<string>;
19
+ lwrkResult: string;
20
+ i, j: integer;
21
+ numMines: integer;
22
+ begin
23
+ result := '';
24
+ lResults := TList<string>.Create;
25
+ Board := aInput.Split(['\n'],none);
26
+ if length(Board) > 0 then
27
+ begin
28
+ for i := 0 to length(Board) - 1 do
29
+ begin
30
+ lwrkResult := '';
31
+ for j := 1 to length(Board[0]) do
32
+ begin
33
+ if board[i,j] = '*' then
34
+ lwrkResult := lwrkResult + '*'
35
+ else
36
+ begin
37
+ numMines := GetCountForSquare(Board, i, j);
38
+ lwrkResult := lwrkResult + ifthen(numMines = 0, ' ', numMines.ToString);
39
+ end;
40
+ end;
41
+ lResults.Add(lwrkResult);
42
+ end;
43
+ result := result.Join('\n',lResults.ToArray);
44
+ end;
45
+ end;
46
+
47
+ class function TMineSweeper.GetCountForSquare(board: array of string; x, y: integer): integer;
48
+ var i, j: integer;
49
+ begin
50
+ result := 0;
51
+ for i := -1 to 1 do
52
+ for j := -1 to 1 do
53
+ try
54
+ {$IFOPT R-}
55
+ {$DEFINE CKRANGEOFF}
56
+ {$R+}
57
+ {$ENDIF}
58
+ if board[x + i, y + j] = '*' then
59
+ inc(result);
60
+ {$IFDEF CKRANGEOFF}
61
+ {$UNDEF CKRANGEOFF}
62
+ {$R-}
63
+ {$ENDIF}
64
+ except
65
+ on ERangeError do
66
+ continue;
67
+ end;
68
+ end;
69
+
70
+ end.
@@ -0,0 +1,270 @@
1
+ unit uMineSweeperTest;
2
+
3
+ interface
4
+ uses
5
+ DUnitX.TestFramework;
6
+
7
+ type
8
+
9
+ [TestFixture]
10
+ MineSweeperTest = class(TObject)
11
+ private
12
+ class function FormatInput(aInput: array of string): string; static;
13
+ public
14
+ [Test]
15
+ // [Ignore('Comment the "[Ignore]" statement to run the test')]
16
+ procedure No_rows;
17
+
18
+ [Test]
19
+ [Ignore]
20
+ procedure No_columns;
21
+
22
+ [Test]
23
+ [Ignore]
24
+ procedure No_mines;
25
+
26
+ [Test]
27
+ [Ignore]
28
+ procedure Board_with_only_mines;
29
+
30
+ [Test]
31
+ [Ignore]
32
+ procedure Mine_surrounded_by_spaces;
33
+
34
+ [Test]
35
+ [Ignore]
36
+ procedure Space_surrounded_by_mines;
37
+
38
+ [Test]
39
+ [Ignore]
40
+ procedure Horizontal_line;
41
+
42
+ [Test]
43
+ [Ignore]
44
+ procedure Horizontal_line_mines_at_edges;
45
+
46
+ [Test]
47
+ [Ignore]
48
+ procedure Vertical_line;
49
+
50
+ [Test]
51
+ [Ignore]
52
+ procedure Vertical_line_mines_at_edges;
53
+
54
+ [Test]
55
+ [Ignore]
56
+ procedure Cross;
57
+
58
+ [Test]
59
+ [Ignore]
60
+ procedure Large_board;
61
+ end;
62
+
63
+ implementation
64
+ uses System.SysUtils, uMineSweeper;
65
+
66
+
67
+ { MineSweeperTest }
68
+
69
+ procedure MineSweeperTest.Board_with_only_mines;
70
+ var input,
71
+ expected: array of string;
72
+ begin
73
+ SetLength(input, 3);
74
+ input[0] := '***';
75
+ input[1] := '***';
76
+ input[2] := '***';
77
+
78
+ SetLength(expected, 3);
79
+ expected[0] := '***';
80
+ expected[1] := '***';
81
+ expected[2] := '***';
82
+
83
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
84
+ end;
85
+
86
+ procedure MineSweeperTest.Cross;
87
+ var input,
88
+ expected: array of string;
89
+ begin
90
+ SetLength(input, 5);
91
+ input[0] := ' * ';
92
+ input[1] := ' * ';
93
+ input[2] := '*****';
94
+ input[3] := ' * ';
95
+ input[4] := ' * ';
96
+
97
+ SetLength(expected, 5);
98
+ expected[0] := ' 2*2 ';
99
+ expected[1] := '25*52';
100
+ expected[2] := '*****';
101
+ expected[3] := '25*52';
102
+ expected[4] := ' 2*2 ';
103
+
104
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
105
+ end;
106
+
107
+ procedure MineSweeperTest.Horizontal_line;
108
+ var input,
109
+ expected: array of string;
110
+ begin
111
+ SetLength(input, 1);
112
+ input[0] := ' * * ';
113
+
114
+ SetLength(expected, 1);
115
+ expected[0] := '1*2*1';
116
+
117
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
118
+ end;
119
+
120
+ procedure MineSweeperTest.Horizontal_line_mines_at_edges;
121
+ var input,
122
+ expected: array of string;
123
+ begin
124
+ SetLength(input, 1);
125
+ input[0] := '* *';
126
+
127
+ SetLength(expected, 1);
128
+ expected[0] := '*1 1*';
129
+
130
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
131
+ end;
132
+
133
+ procedure MineSweeperTest.Large_board;
134
+ var input,
135
+ expected: array of string;
136
+ begin
137
+ SetLength(input, 6);
138
+ input[0] := ' * * ';
139
+ input[1] := ' * ';
140
+ input[2] := ' * ';
141
+ input[3] := ' * *';
142
+ input[4] := ' * * ';
143
+ input[5] := ' ';
144
+
145
+ SetLength(expected, 6);
146
+ expected[0] := '1*22*1';
147
+ expected[1] := '12*322';
148
+ expected[2] := ' 123*2';
149
+ expected[3] := '112*4*';
150
+ expected[4] := '1*22*2';
151
+ expected[5] := '111111';
152
+
153
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
154
+ end;
155
+
156
+ procedure MineSweeperTest.Mine_surrounded_by_spaces;
157
+ var input,
158
+ expected: array of string;
159
+ begin
160
+ SetLength(input, 3);
161
+ input[0] := ' ';
162
+ input[1] := ' * ';
163
+ input[2] := ' ';
164
+
165
+ SetLength(expected, 3);
166
+ expected[0] := '111';
167
+ expected[1] := '1*1';
168
+ expected[2] := '111';
169
+
170
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
171
+ end;
172
+
173
+ procedure MineSweeperTest.No_columns;
174
+ var input: array of string;
175
+ begin
176
+ SetLength(input, 1);
177
+ input[0] := '';
178
+ Assert.AreEqual('', TMineSweeper.Annotate(FormatInput(input)));
179
+ end;
180
+
181
+ procedure MineSweeperTest.No_mines;
182
+ var input,
183
+ expected: array of string;
184
+ begin
185
+ SetLength(input, 3);
186
+ input[0] := ' ';
187
+ input[1] := ' ';
188
+ input[2] := ' ';
189
+
190
+ SetLength(expected, 3);
191
+ expected[0] := ' ';
192
+ expected[1] := ' ';
193
+ expected[2] := ' ';
194
+
195
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
196
+ end;
197
+
198
+ procedure MineSweeperTest.No_rows;
199
+ begin
200
+ Assert.AreEqual('', TMineSweeper.Annotate(''));
201
+ end;
202
+
203
+ procedure MineSweeperTest.Space_surrounded_by_mines;
204
+ var input,
205
+ expected: array of string;
206
+ begin
207
+ SetLength(input, 3);
208
+ input[0] := '***';
209
+ input[1] := '* *';
210
+ input[2] := '***';
211
+
212
+ SetLength(expected, 3);
213
+ expected[0] := '***';
214
+ expected[1] := '*8*';
215
+ expected[2] := '***';
216
+
217
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
218
+ end;
219
+
220
+ procedure MineSweeperTest.Vertical_line;
221
+ var input,
222
+ expected: array of string;
223
+ begin
224
+ SetLength(input, 5);
225
+ input[0] := ' ';
226
+ input[1] := '*';
227
+ input[2] := ' ';
228
+ input[3] := '*';
229
+ input[4] := ' ';
230
+
231
+ SetLength(expected, 5);
232
+ expected[0] := '1';
233
+ expected[1] := '*';
234
+ expected[2] := '2';
235
+ expected[3] := '*';
236
+ expected[4] := '1';
237
+
238
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
239
+ end;
240
+
241
+ procedure MineSweeperTest.Vertical_line_mines_at_edges;
242
+ var input,
243
+ expected: array of string;
244
+ begin
245
+ SetLength(input, 5);
246
+ input[0] := '*';
247
+ input[1] := ' ';
248
+ input[2] := ' ';
249
+ input[3] := ' ';
250
+ input[4] := '*';
251
+
252
+ SetLength(expected, 5);
253
+ expected[0] := '*';
254
+ expected[1] := '1';
255
+ expected[2] := ' ';
256
+ expected[3] := '1';
257
+ expected[4] := '*';
258
+
259
+ Assert.AreEqual(FormatInput(expected), TMineSweeper.Annotate(FormatInput(input)));
260
+ end;
261
+
262
+ class function MineSweeperTest.FormatInput(aInput: array of string): string;
263
+ begin
264
+ result := '';
265
+ result := result.Join('\n',aInput);
266
+ end;
267
+
268
+ Initialization
269
+ TDUnitX.RegisterTestFixture(MineSweeperTest);
270
+ end.
@@ -24,84 +24,139 @@
24
24
  ],
25
25
  "exercises": [
26
26
  {
27
- "slug": "hello-world" ,
27
+ "slug": "hello-world",
28
28
  "difficulty": 1,
29
- "topics": []
29
+ "topics": [
30
+ "language basics"
31
+ ]
30
32
  },
31
33
  {
32
34
  "slug": "gigasecond" ,
33
35
  "difficulty": 1,
34
- "topics": []
36
+ "topics": [
37
+ "language basics",
38
+ "time"
39
+ ]
35
40
  },
36
41
  {
37
- "slug": "rna-transcription" ,
42
+ "slug": "rna-transcription",
38
43
  "difficulty": 2,
39
- "topics": []
44
+ "topics": [
45
+ "string manipulation",
46
+ "error handling",
47
+ "control-flow (foreach)"
48
+ ]
40
49
  },
41
50
  {
42
- "slug": "raindrops" ,
51
+ "slug": "raindrops",
43
52
  "difficulty": 1,
44
- "topics": []
53
+ "topics": [
54
+ "language basics",
55
+ "control-flow (if-statements)"
56
+ ]
45
57
  },
46
58
  {
47
- "slug": "bob" ,
59
+ "slug": "bob",
48
60
  "difficulty": 2,
49
- "topics": []
61
+ "topics": [
62
+ "string manipulation",
63
+ "control-flow (if-statements)"
64
+ ]
50
65
  },
51
66
  {
52
- "slug": "etl" ,
67
+ "slug": "etl",
53
68
  "difficulty": 2,
54
- "topics": []
69
+ "topics": [
70
+ "string manipulation",
71
+ "control-flow (foreach)",
72
+ "associative arrays"
73
+ ]
55
74
  },
56
75
  {
57
- "slug": "hamming" ,
76
+ "slug": "hamming",
58
77
  "difficulty": 2,
59
- "topics": []
78
+ "topics": [
79
+ "error handling",
80
+ "control-flow (foreach)"
81
+ ]
60
82
  },
61
83
  {
62
- "slug": "nucleotide-count" ,
84
+ "slug": "nucleotide-count",
63
85
  "difficulty": 3,
64
- "topics": []
86
+ "topics": [
87
+ "classes",
88
+ "parsing",
89
+ "associative arrays"
90
+ ]
65
91
  },
66
92
  {
67
- "slug": "robot-name" ,
93
+ "slug": "robot-name",
68
94
  "difficulty": 3,
69
- "topics": []
95
+ "topics": [
96
+ "classes",
97
+ "random numbers"
98
+ ]
70
99
  },
71
100
  {
72
- "slug": "difference-of-squares" ,
101
+ "slug": "difference-of-squares",
73
102
  "difficulty": 2,
74
- "topics": []
103
+ "topics": [
104
+ "control-flow (foreach)",
105
+ "template metaprogramming",
106
+ "functional",
107
+ "algorithms"
108
+ ]
75
109
  },
76
110
  {
77
- "slug": "roman-numerals" ,
111
+ "slug": "roman-numerals",
78
112
  "difficulty": 3,
79
- "topics": []
113
+ "topics": [
114
+ "string manipulation",
115
+ "conversions",
116
+ "functional"
117
+ ]
80
118
  },
81
119
  {
82
- "slug": "series" ,
120
+ "slug": "series",
83
121
  "difficulty": 3,
84
- "topics": []
122
+ "topics": [
123
+ "string manipulation",
124
+ "arrays"
125
+ ]
85
126
  },
86
127
  {
87
- "slug": "triangle" ,
128
+ "slug": "triangle",
88
129
  "difficulty": 2,
89
- "topics": []
130
+ "topics": [
131
+ "language basics",
132
+ "control-flow (if-statements)"
133
+ ]
90
134
  },
91
135
  {
92
- "slug": "crypto-square" ,
136
+ "slug": "crypto-square",
93
137
  "difficulty": 3,
94
- "topics": []
138
+ "topics": [
139
+ "string manipulation",
140
+ "classes",
141
+ "algorithms"
142
+ ]
95
143
  },
96
144
  {
97
- "slug": "circular-buffer" ,
145
+ "slug": "circular-buffer",
98
146
  "difficulty": 4,
99
- "topics": []
147
+ "topics": [
148
+ "class templates",
149
+ "data-structures"
150
+ ]
100
151
  },
101
152
  {
102
- "slug": "pangram" ,
153
+ "slug": "pangram",
103
154
  "difficulty": 1,
104
- "topics": []
155
+ "topics": [
156
+ "language basics",
157
+ "string manipulation",
158
+ "control-flow"
159
+ ]
105
160
  }
106
161
  ],
107
162
  "deprecated": [