trackler 2.2.1.137 → 2.2.1.138
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/diffie-hellman/canonical-data.json +72 -0
- data/problem-specifications/exercises/yacht/description.md +2 -2
- data/tracks/csharp/exercises/sgf-parsing/Example.cs +1 -1
- data/tracks/csharp/exercises/sgf-parsing/SgfParsingTest.cs +1 -1
- data/tracks/csharp/exercises/sublist/SublistTest.cs +37 -78
- data/tracks/csharp/generators/Exercises/Sublist.cs +32 -0
- data/tracks/elisp/exercises/bob/README.md +2 -0
- data/tracks/elisp/exercises/bob/bob-test.el +60 -15
- data/tracks/elisp/exercises/bob/example.el +15 -5
- data/tracks/elisp/exercises/hamming/hamming-test.el +1 -1
- data/tracks/fsharp/build.ps1 +3 -3
- data/tracks/fsharp/build.sh +3 -3
- data/tracks/fsharp/exercises/bracket-push/BracketPushTest.fs +5 -1
- data/tracks/fsharp/exercises/isbn-verifier/IsbnVerifierTest.fs +5 -1
- data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGardenTest.fs +1 -1
- data/tracks/fsharp/exercises/pov/PovTest.fs +6 -1
- data/tracks/fsharp/exercises/react/Example.fs +2 -2
- data/tracks/fsharp/exercises/react/React.fsproj +1 -0
- data/tracks/fsharp/exercises/react/ReactTest.fs +55 -33
- data/tracks/fsharp/exercises/series/Example.fs +2 -12
- data/tracks/fsharp/exercises/series/SeriesTest.fs +33 -56
- data/tracks/fsharp/generators/Generators.fs +81 -46
- data/tracks/idris/exercises/rna-transcription/src/{example.idr → Example.idr} +0 -0
- data/tracks/java/config.json +14 -0
- data/tracks/java/exercises/acronym/src/test/java/AcronymTest.java +10 -10
- data/tracks/java/exercises/all-your-base/src/test/java/BaseConverterTest.java +39 -39
- data/tracks/java/exercises/grep/.meta/hints.md +58 -0
- data/tracks/java/exercises/grep/.meta/src/reference/java/GrepTool.java +65 -0
- data/tracks/java/exercises/grep/.meta/version +1 -0
- data/tracks/java/exercises/grep/README.md +145 -0
- data/tracks/java/exercises/grep/build.gradle +18 -0
- data/tracks/java/exercises/grep/src/main/java/.keep +0 -0
- data/tracks/java/exercises/grep/src/test/java/GrepToolTest.java +395 -0
- data/tracks/java/exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java +36 -36
- data/tracks/java/exercises/minesweeper/src/test/java/MinesweeperBoardTest.java +36 -36
- data/tracks/java/exercises/phone-number/src/test/java/PhoneNumberTest.java +14 -14
- data/tracks/java/exercises/poker/src/test/java/PokerTest.java +40 -40
- data/tracks/java/exercises/pythagorean-triplet/src/test/java/PythagoreanTripletTest.java +10 -10
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/ocaml/exercises/anagram/example.ml +1 -1
- data/tracks/ocaml/exercises/change/example.ml +1 -1
- data/tracks/ocaml/exercises/custom-set/example.ml +4 -3
- data/tracks/ocaml/exercises/custom-set/test.ml +0 -1
- data/tracks/ocaml/exercises/dominoes/test.ml +1 -1
- data/tracks/ocaml/exercises/etl/example.ml +1 -1
- data/tracks/ocaml/exercises/grade-school/example.ml +1 -1
- data/tracks/ocaml/exercises/palindrome-products/example.ml +2 -2
- data/tracks/ocaml/exercises/prime-factors/example.ml +1 -1
- data/tracks/ocaml/exercises/robot-name/test.ml +1 -1
- data/tracks/ocaml/exercises/triangle/example.ml +1 -1
- data/tracks/ocaml/make-exercise.sh +1 -0
- data/tracks/ocaml/tools/test-generator/src/controller.ml +1 -1
- data/tracks/perl5/exercises/raindrops/.meta/solutions/Raindrops.pm +13 -12
- data/tracks/perl5/exercises/raindrops/raindrops.t +166 -111
- data/tracks/perl6/docs/INSTALLATION.md +1 -3
- data/tracks/perl6/exercises/raindrops/.meta/exercise-data.yaml +5 -5
- data/tracks/perl6/exercises/raindrops/.meta/solutions/Raindrops.pm6 +2 -2
- data/tracks/perl6/exercises/raindrops/Raindrops.pm6 +2 -2
- data/tracks/perl6/exercises/raindrops/raindrops.t +3 -3
- data/tracks/python/exercises/food-chain/example.py +11 -2
- data/tracks/python/exercises/food-chain/food_chain_test.py +48 -45
- data/tracks/python/exercises/pov/pov_test.py +12 -1
- data/tracks/python/exercises/series/README.md +6 -6
- data/tracks/python/exercises/series/example.py +2 -3
- data/tracks/python/exercises/series/series_test.py +27 -28
- data/tracks/python/exercises/sgf-parsing/example.py +1 -1
- data/tracks/python/exercises/sgf-parsing/sgf_parsing_test.py +1 -1
- data/tracks/python/exercises/yacht/README.md +2 -2
- data/tracks/ruby/Gemfile +0 -1
- data/tracks/ruby/README.md +23 -0
- data/tracks/ruby/bin/generate +1 -0
- data/tracks/ruby/exercises/complex-numbers/complex_numbers_test.rb +1 -1
- data/tracks/ruby/lib/generator.rb +1 -2
- data/tracks/ruby/lib/generator/command_line.rb +3 -0
- data/tracks/ruby/lib/generator/command_line/generator_optparser.rb +1 -0
- data/tracks/ruby/lib/generator/exercise.rb +2 -0
- data/tracks/ruby/lib/generator/exercise_case.rb +3 -0
- data/tracks/ruby/lib/generator/files.rb +1 -0
- data/tracks/ruby/lib/generator/files/metadata_files.rb +2 -0
- data/tracks/ruby/lib/generator/files/track_files.rb +1 -0
- data/tracks/ruby/lib/generator/implementation.rb +1 -0
- data/tracks/ruby/lib/generator/repository.rb +3 -0
- data/tracks/ruby/lib/generator/template_values.rb +1 -0
- data/tracks/ruby/test/generator/case_values_test.rb +2 -0
- data/tracks/ruby/test/generator/command_line_test.rb +1 -0
- data/tracks/ruby/test/generator/files/metadata_files_test.rb +2 -0
- data/tracks/ruby/test/generator/files/track_files_test.rb +1 -0
- data/tracks/ruby/test/generator/implementation_test.rb +1 -0
- data/tracks/ruby/test/tasks/exercise_test.rb +1 -0
- data/tracks/ruby/test/tasks/exercise_test_tasks_test.rb +2 -0
- data/tracks/ruby/test/test_helper.rb +1 -3
- data/tracks/rust/config.json +12 -0
- data/tracks/rust/exercises/atbash-cipher/src/lib.rs +9 -0
- data/tracks/rust/exercises/hamming/src/lib.rs +6 -0
- data/tracks/rust/exercises/isogram/src/lib.rs +3 -0
- data/tracks/rust/exercises/luhn/src/lib.rs +4 -0
- data/tracks/rust/exercises/palindrome-products/.meta/test-in-release-mode +1 -0
- data/tracks/rust/exercises/palindrome-products/Cargo.toml +6 -0
- data/tracks/rust/exercises/palindrome-products/README.md +72 -0
- data/tracks/rust/exercises/palindrome-products/example.rs +25 -0
- data/tracks/rust/exercises/palindrome-products/src/lib.rs +22 -0
- data/tracks/rust/exercises/palindrome-products/tests/palindrome-products.rs +57 -0
- data/tracks/rust/exercises/pangram/src/lib.rs +4 -0
- data/tracks/rust/exercises/run-length-encoding/src/lib.rs +7 -0
- data/tracks/rust/exercises/say/src/lib.rs +3 -4
- data/tracks/rust/exercises/scrabble-score/src/lib.rs +4 -0
- data/tracks/rust/exercises/word-count/src/lib.rs +6 -0
- data/tracks/scheme/exercises/hello-world/example.scm +1 -4
- data/tracks/scheme/exercises/hello-world/hello-world-test.scm +1 -5
- data/tracks/scheme/exercises/scrabble-score/scrabble-score-test.scm +2 -2
- data/tracks/typescript/config.json +30 -0
- data/tracks/typescript/exercises/queen-attack/README.md +59 -0
- data/tracks/typescript/exercises/queen-attack/package.json +36 -0
- data/tracks/typescript/exercises/queen-attack/queen-attack.example.ts +56 -0
- data/tracks/typescript/exercises/queen-attack/queen-attack.test.ts +71 -0
- data/tracks/typescript/exercises/queen-attack/queen-attack.ts +0 -0
- data/tracks/typescript/exercises/queen-attack/tsconfig.json +22 -0
- data/tracks/typescript/exercises/queen-attack/tslint.json +127 -0
- data/tracks/typescript/exercises/queen-attack/yarn.lock +2624 -0
- data/tracks/typescript/exercises/spiral-matrix/README.md +56 -0
- data/tracks/typescript/exercises/spiral-matrix/package.json +36 -0
- data/tracks/typescript/exercises/spiral-matrix/spiral-matrix.example.ts +33 -0
- data/tracks/typescript/exercises/spiral-matrix/spiral-matrix.test.ts +49 -0
- data/tracks/typescript/exercises/spiral-matrix/spiral-matrix.ts +0 -0
- data/tracks/typescript/exercises/spiral-matrix/tsconfig.json +22 -0
- data/tracks/typescript/exercises/spiral-matrix/tslint.json +127 -0
- data/tracks/typescript/exercises/spiral-matrix/yarn.lock +2624 -0
- metadata +35 -3
File without changes
|
data/tracks/java/config.json
CHANGED
@@ -638,6 +638,20 @@
|
|
638
638
|
"unlocked_by": "rotational-cipher",
|
639
639
|
"uuid": "d36ce010-210f-4e9a-9d6c-cb933e0a59af"
|
640
640
|
},
|
641
|
+
{
|
642
|
+
"core": false,
|
643
|
+
"difficulty": 5,
|
644
|
+
"slug": "grep",
|
645
|
+
"topics": [
|
646
|
+
"pattern_matching",
|
647
|
+
"strings",
|
648
|
+
"files",
|
649
|
+
"filtering",
|
650
|
+
"searching"
|
651
|
+
],
|
652
|
+
"unlocked_by": "robot-name",
|
653
|
+
"uuid": "9c15ddab-7b52-43d4-b38c-0bf635b363c3"
|
654
|
+
},
|
641
655
|
{
|
642
656
|
"core": false,
|
643
657
|
"difficulty": 6,
|
@@ -7,40 +7,40 @@ public class AcronymTest {
|
|
7
7
|
|
8
8
|
@Test
|
9
9
|
public void basic() {
|
10
|
-
|
11
|
-
|
10
|
+
String phrase = "Portable Network Graphics";
|
11
|
+
String expected = "PNG";
|
12
12
|
assertEquals(expected, new Acronym(phrase).get());
|
13
13
|
}
|
14
14
|
|
15
15
|
@Ignore("Remove to run test")
|
16
16
|
@Test
|
17
17
|
public void lowercaseWords() {
|
18
|
-
|
19
|
-
|
18
|
+
String phrase = "Ruby on Rails";
|
19
|
+
String expected = "ROR";
|
20
20
|
assertEquals(expected, new Acronym(phrase).get());
|
21
21
|
}
|
22
22
|
|
23
23
|
@Ignore("Remove to run test")
|
24
24
|
@Test
|
25
25
|
public void punctuation() {
|
26
|
-
|
27
|
-
|
26
|
+
String phrase = "First In, First Out";
|
27
|
+
String expected = "FIFO";
|
28
28
|
assertEquals(expected, new Acronym(phrase).get());
|
29
29
|
}
|
30
30
|
|
31
31
|
@Ignore("Remove to run test")
|
32
32
|
@Test
|
33
33
|
public void NonAcronymAllCapsWord() {
|
34
|
-
|
35
|
-
|
34
|
+
String phrase = "GNU Image Manipulation Program";
|
35
|
+
String expected = "GIMP";
|
36
36
|
assertEquals(expected, new Acronym(phrase).get());
|
37
37
|
}
|
38
38
|
|
39
39
|
@Ignore("Remove to run test")
|
40
40
|
@Test
|
41
41
|
public void punctuationWithoutWhitespace() {
|
42
|
-
|
43
|
-
|
42
|
+
String phrase = "Complementary metal-oxide semiconductor";
|
43
|
+
String expected = "CMOS";
|
44
44
|
assertEquals(expected, new Acronym(phrase).get());
|
45
45
|
}
|
46
46
|
|
@@ -14,10 +14,10 @@ public class BaseConverterTest {
|
|
14
14
|
|
15
15
|
@Test
|
16
16
|
public void testSingleBitOneToDecimal() {
|
17
|
-
|
17
|
+
BaseConverter baseConverter = new BaseConverter(2, new int[]{1});
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
int[] expectedDigits = new int[]{1};
|
20
|
+
int[] actualDigits = baseConverter.convertToBase(10);
|
21
21
|
|
22
22
|
assertArrayEquals(
|
23
23
|
String.format(
|
@@ -31,10 +31,10 @@ public class BaseConverterTest {
|
|
31
31
|
@Ignore("Remove to run test")
|
32
32
|
@Test
|
33
33
|
public void testBinaryToSingleDecimal() {
|
34
|
-
|
34
|
+
BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1});
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
int[] expectedDigits = new int[]{5};
|
37
|
+
int[] actualDigits = baseConverter.convertToBase(10);
|
38
38
|
|
39
39
|
assertArrayEquals(
|
40
40
|
String.format(
|
@@ -48,10 +48,10 @@ public class BaseConverterTest {
|
|
48
48
|
@Ignore("Remove to run test")
|
49
49
|
@Test
|
50
50
|
public void testSingleDecimalToBinary() {
|
51
|
-
|
51
|
+
BaseConverter baseConverter = new BaseConverter(10, new int[]{5});
|
52
52
|
|
53
|
-
|
54
|
-
|
53
|
+
int[] expectedDigits = new int[]{1, 0, 1};
|
54
|
+
int[] actualDigits = baseConverter.convertToBase(2);
|
55
55
|
|
56
56
|
assertArrayEquals(
|
57
57
|
String.format(
|
@@ -65,10 +65,10 @@ public class BaseConverterTest {
|
|
65
65
|
@Ignore("Remove to run test")
|
66
66
|
@Test
|
67
67
|
public void testBinaryToMultipleDecimal() {
|
68
|
-
|
68
|
+
BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1, 0, 1, 0});
|
69
69
|
|
70
|
-
|
71
|
-
|
70
|
+
int[] expectedDigits = new int[]{4, 2};
|
71
|
+
int[] actualDigits = baseConverter.convertToBase(10);
|
72
72
|
|
73
73
|
assertArrayEquals(
|
74
74
|
String.format(
|
@@ -82,10 +82,10 @@ public class BaseConverterTest {
|
|
82
82
|
@Ignore("Remove to run test")
|
83
83
|
@Test
|
84
84
|
public void testDecimalToBinary() {
|
85
|
-
|
85
|
+
BaseConverter baseConverter = new BaseConverter(10, new int[]{4, 2});
|
86
86
|
|
87
|
-
|
88
|
-
|
87
|
+
int[] expectedDigits = new int[]{1, 0, 1, 0, 1, 0};
|
88
|
+
int[] actualDigits = baseConverter.convertToBase(2);
|
89
89
|
|
90
90
|
assertArrayEquals(
|
91
91
|
String.format(
|
@@ -99,10 +99,10 @@ public class BaseConverterTest {
|
|
99
99
|
@Ignore("Remove to run test")
|
100
100
|
@Test
|
101
101
|
public void testTrinaryToHexadecimal() {
|
102
|
-
|
102
|
+
BaseConverter baseConverter = new BaseConverter(3, new int[]{1, 1, 2, 0});
|
103
103
|
|
104
|
-
|
105
|
-
|
104
|
+
int[] expectedDigits = new int[]{2, 10};
|
105
|
+
int[] actualDigits = baseConverter.convertToBase(16);
|
106
106
|
|
107
107
|
assertArrayEquals(
|
108
108
|
String.format(
|
@@ -116,10 +116,10 @@ public class BaseConverterTest {
|
|
116
116
|
@Ignore("Remove to run test")
|
117
117
|
@Test
|
118
118
|
public void testHexadecimalToTrinary() {
|
119
|
-
|
119
|
+
BaseConverter baseConverter = new BaseConverter(16, new int[]{2, 10});
|
120
120
|
|
121
|
-
|
122
|
-
|
121
|
+
int[] expectedDigits = new int[]{1, 1, 2, 0};
|
122
|
+
int[] actualDigits = baseConverter.convertToBase(3);
|
123
123
|
|
124
124
|
assertArrayEquals(
|
125
125
|
String.format(
|
@@ -133,10 +133,10 @@ public class BaseConverterTest {
|
|
133
133
|
@Ignore("Remove to run test")
|
134
134
|
@Test
|
135
135
|
public void test15BitInteger() {
|
136
|
-
|
136
|
+
BaseConverter baseConverter = new BaseConverter(97, new int[]{3, 46, 60});
|
137
137
|
|
138
|
-
|
139
|
-
|
138
|
+
int[] expectedDigits = new int[]{6, 10, 45};
|
139
|
+
int[] actualDigits = baseConverter.convertToBase(73);
|
140
140
|
|
141
141
|
assertArrayEquals(
|
142
142
|
String.format(
|
@@ -150,10 +150,10 @@ public class BaseConverterTest {
|
|
150
150
|
@Ignore("Remove to run test")
|
151
151
|
@Test
|
152
152
|
public void testEmptyDigits() {
|
153
|
-
|
153
|
+
BaseConverter baseConverter = new BaseConverter(2, new int[]{});
|
154
154
|
|
155
|
-
|
156
|
-
|
155
|
+
int[] expectedDigits = new int[]{0};
|
156
|
+
int[] actualDigits = baseConverter.convertToBase(10);
|
157
157
|
|
158
158
|
assertArrayEquals(
|
159
159
|
String.format(
|
@@ -167,10 +167,10 @@ public class BaseConverterTest {
|
|
167
167
|
@Ignore("Remove to run test")
|
168
168
|
@Test
|
169
169
|
public void testSingleZero() {
|
170
|
-
|
170
|
+
BaseConverter baseConverter = new BaseConverter(10, new int[]{0});
|
171
171
|
|
172
|
-
|
173
|
-
|
172
|
+
int[] expectedDigits = new int[]{0};
|
173
|
+
int[] actualDigits = baseConverter.convertToBase(2);
|
174
174
|
|
175
175
|
assertArrayEquals(
|
176
176
|
String.format(
|
@@ -184,10 +184,10 @@ public class BaseConverterTest {
|
|
184
184
|
@Ignore("Remove to run test")
|
185
185
|
@Test
|
186
186
|
public void testMultipleZeros() {
|
187
|
-
|
187
|
+
BaseConverter baseConverter = new BaseConverter(10, new int[]{0, 0, 0});
|
188
188
|
|
189
|
-
|
190
|
-
|
189
|
+
int[] expectedDigits = new int[]{0};
|
190
|
+
int[] actualDigits = baseConverter.convertToBase(2);
|
191
191
|
|
192
192
|
assertArrayEquals(
|
193
193
|
String.format(
|
@@ -201,10 +201,10 @@ public class BaseConverterTest {
|
|
201
201
|
@Ignore("Remove to run test")
|
202
202
|
@Test
|
203
203
|
public void testLeadingZeros() {
|
204
|
-
|
204
|
+
BaseConverter baseConverter = new BaseConverter(7, new int[]{0, 6, 0});
|
205
205
|
|
206
|
-
|
207
|
-
|
206
|
+
int[] expectedDigits = new int[]{4, 2};
|
207
|
+
int[] actualDigits = baseConverter.convertToBase(10);
|
208
208
|
|
209
209
|
assertArrayEquals(
|
210
210
|
String.format(
|
@@ -263,7 +263,7 @@ public class BaseConverterTest {
|
|
263
263
|
@Ignore("Remove to run test")
|
264
264
|
@Test
|
265
265
|
public void testSecondBaseIsOne() {
|
266
|
-
|
266
|
+
BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1, 0, 1, 0});
|
267
267
|
|
268
268
|
expectedException.expect(IllegalArgumentException.class);
|
269
269
|
expectedException.expectMessage("Bases must be at least 2.");
|
@@ -274,7 +274,7 @@ public class BaseConverterTest {
|
|
274
274
|
@Ignore("Remove to run test")
|
275
275
|
@Test
|
276
276
|
public void testSecondBaseIsZero() {
|
277
|
-
|
277
|
+
BaseConverter baseConverter = new BaseConverter(10, new int[]{7});
|
278
278
|
|
279
279
|
expectedException.expect(IllegalArgumentException.class);
|
280
280
|
expectedException.expectMessage("Bases must be at least 2.");
|
@@ -285,7 +285,7 @@ public class BaseConverterTest {
|
|
285
285
|
@Ignore("Remove to run test")
|
286
286
|
@Test
|
287
287
|
public void testSecondBaseIsNegative() {
|
288
|
-
|
288
|
+
BaseConverter baseConverter = new BaseConverter(2, new int[]{1});
|
289
289
|
|
290
290
|
expectedException.expect(IllegalArgumentException.class);
|
291
291
|
expectedException.expectMessage("Bases must be at least 2.");
|
@@ -0,0 +1,58 @@
|
|
1
|
+
Since this exercise has difficulty 5 it doesn't come with any starter implementation.
|
2
|
+
This is so that you get to practice creating classes and methods which is an important part of programming in Java.
|
3
|
+
It does mean that when you first try to run the tests, they won't compile.
|
4
|
+
They will give you an error similar to:
|
5
|
+
```
|
6
|
+
path-to-exercism-dir\exercism\java\name-of-exercise\src\test\java\ExerciseClassNameTest.java:14: error: cannot find symbol
|
7
|
+
ExerciseClassName exerciseClassName = new ExerciseClassName();
|
8
|
+
^
|
9
|
+
symbol: class ExerciseClassName
|
10
|
+
location: class ExerciseClassNameTest
|
11
|
+
```
|
12
|
+
This error occurs because the test refers to a class that hasn't been created yet (`ExerciseClassName`).
|
13
|
+
To resolve the error you need to add a file matching the class name in the error to the `src/main/java` directory.
|
14
|
+
For example, for the error above you would add a file called `ExerciseClassName.java`.
|
15
|
+
|
16
|
+
When you try to run the tests again you will get slightly different errors.
|
17
|
+
You might get an error similar to:
|
18
|
+
```
|
19
|
+
constructor ExerciseClassName in class ExerciseClassName cannot be applied to given types;
|
20
|
+
ExerciseClassName exerciseClassName = new ExerciseClassName("some argument");
|
21
|
+
^
|
22
|
+
required: no arguments
|
23
|
+
found: String
|
24
|
+
reason: actual and formal argument lists differ in length
|
25
|
+
```
|
26
|
+
This error means that you need to add a [constructor](https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html) to your new class.
|
27
|
+
If you don't add a constructor, Java will add a default one for you.
|
28
|
+
This default constructor takes no arguments.
|
29
|
+
So if the tests expect your class to have a constructor which takes arguments, then you need to create this constructor yourself.
|
30
|
+
In the example above you could add:
|
31
|
+
```
|
32
|
+
ExerciseClassName(String input) {
|
33
|
+
|
34
|
+
}
|
35
|
+
```
|
36
|
+
That should make the error go away, though you might need to add some more code to your constructor to make the test pass!
|
37
|
+
|
38
|
+
You might also get an error similar to:
|
39
|
+
```
|
40
|
+
error: cannot find symbol
|
41
|
+
assertEquals(expectedOutput, exerciseClassName.someMethod());
|
42
|
+
^
|
43
|
+
symbol: method someMethod()
|
44
|
+
location: variable exerciseClassName of type ExerciseClassName
|
45
|
+
```
|
46
|
+
This error means that you need to add a method called `someMethod` to your new class.
|
47
|
+
In the example above you would add:
|
48
|
+
```
|
49
|
+
String someMethod() {
|
50
|
+
return "";
|
51
|
+
}
|
52
|
+
```
|
53
|
+
Make sure the return type matches what the test is expecting.
|
54
|
+
You can find out which return type it should have by looking at the type of object it's being compared to in the tests.
|
55
|
+
Or you could set your method to return some random type (e.g. `void`), and run the tests again.
|
56
|
+
The new error should tell you which type it's expecting.
|
57
|
+
|
58
|
+
After having resolved these errors you should be ready to start making the tests pass!
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import java.io.IOException;
|
2
|
+
import java.nio.charset.Charset;
|
3
|
+
import java.nio.file.Files;
|
4
|
+
import java.nio.file.Paths;
|
5
|
+
import java.util.Collections;
|
6
|
+
import java.util.List;
|
7
|
+
import java.util.stream.Collectors;
|
8
|
+
import java.util.stream.IntStream;
|
9
|
+
|
10
|
+
class GrepTool {
|
11
|
+
|
12
|
+
String grep(String pattern, List<String> flags, List<String> files) {
|
13
|
+
boolean shouldAddFilenameToEachLine = files.size() > 1;
|
14
|
+
return files
|
15
|
+
.stream()
|
16
|
+
.map(file -> grepFile(pattern, flags, file, shouldAddFilenameToEachLine))
|
17
|
+
.filter(line -> !line.isEmpty())
|
18
|
+
.collect(Collectors.joining("\n"));
|
19
|
+
}
|
20
|
+
|
21
|
+
private String grepFile(String pattern, List<String> flags, String filename, boolean shouldAddFilenameToEachLine) {
|
22
|
+
List<String> lines = readFile(filename);
|
23
|
+
|
24
|
+
String matchingLines = IntStream.range(0, lines.size())
|
25
|
+
.filter(lineIndex -> lineMatchesPattern(lines.get(lineIndex), pattern, flags))
|
26
|
+
.mapToObj(lineIndex -> {
|
27
|
+
String lineWithFlagsApplied = applyFlagsToLine(lines.get(lineIndex), flags, lineIndex + 1);
|
28
|
+
return shouldAddFilenameToEachLine ? filename + ":" + lineWithFlagsApplied : lineWithFlagsApplied;
|
29
|
+
})
|
30
|
+
.collect(Collectors.joining("\n"));
|
31
|
+
|
32
|
+
boolean shouldPrintFilenameInsteadOfMatchingLines = flags.contains("-l");
|
33
|
+
return shouldPrintFilenameInsteadOfMatchingLines && !matchingLines.isEmpty() ? filename : matchingLines;
|
34
|
+
}
|
35
|
+
|
36
|
+
private boolean lineMatchesPattern(String line, String pattern, List<String> flags) {
|
37
|
+
boolean isCaseInsensitive = flags.contains("-i");
|
38
|
+
String lineToCompare = isCaseInsensitive ? line.toLowerCase() : line;
|
39
|
+
String patternToCompare = isCaseInsensitive ? pattern.toLowerCase() : pattern;
|
40
|
+
|
41
|
+
boolean shouldMatchEntireLine = flags.contains("-x");
|
42
|
+
boolean matchesPattern = shouldMatchEntireLine
|
43
|
+
? lineToCompare.equals(patternToCompare)
|
44
|
+
: lineToCompare.contains(patternToCompare);
|
45
|
+
|
46
|
+
boolean shouldInvertMatch = flags.contains("-v");
|
47
|
+
//noinspection SimplifiableConditionalExpression
|
48
|
+
return shouldInvertMatch ? !matchesPattern : matchesPattern;
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
private String applyFlagsToLine(String line, List<String> flags, int lineNumber) {
|
53
|
+
boolean shouldAddLineNumber = flags.contains("-n");
|
54
|
+
return shouldAddLineNumber ? lineNumber + ":" + line : line;
|
55
|
+
}
|
56
|
+
|
57
|
+
private List<String> readFile(String filename) {
|
58
|
+
try {
|
59
|
+
return Files.readAllLines(Paths.get(filename), Charset.forName("UTF-8"));
|
60
|
+
} catch (IOException e) {
|
61
|
+
return Collections.emptyList();
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
1.1.0
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Grep
|
2
|
+
|
3
|
+
Search a file for lines matching a regular expression pattern. Return the line
|
4
|
+
number and contents of each matching line.
|
5
|
+
|
6
|
+
The Unix [`grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html) command can be used to search for lines in one or more files
|
7
|
+
that match a user-provided search query (known as the *pattern*).
|
8
|
+
|
9
|
+
The `grep` command takes three arguments:
|
10
|
+
|
11
|
+
1. The pattern used to match lines in a file.
|
12
|
+
2. Zero or more flags to customize the matching behavior.
|
13
|
+
3. One or more files in which to search for matching lines.
|
14
|
+
|
15
|
+
Your task is to implement the `grep` function, which should read the contents
|
16
|
+
of the specified files, find the lines that match the specified pattern
|
17
|
+
and then output those lines as a single string. Note that the lines should
|
18
|
+
be output in the order in which they were found, with the first matching line
|
19
|
+
in the first file being output first.
|
20
|
+
|
21
|
+
As an example, suppose there is a file named "input.txt" with the following contents:
|
22
|
+
|
23
|
+
```text
|
24
|
+
hello
|
25
|
+
world
|
26
|
+
hello again
|
27
|
+
```
|
28
|
+
|
29
|
+
If we were to call `grep "hello" input.txt`, the returned string should be:
|
30
|
+
|
31
|
+
```text
|
32
|
+
hello
|
33
|
+
hello again
|
34
|
+
```
|
35
|
+
|
36
|
+
### Flags
|
37
|
+
|
38
|
+
As said earlier, the `grep` command should also support the following flags:
|
39
|
+
|
40
|
+
- `-n` Print the line numbers of each matching line.
|
41
|
+
- `-l` Print only the names of files that contain at least one matching line.
|
42
|
+
- `-i` Match line using a case-insensitive comparison.
|
43
|
+
- `-v` Invert the program -- collect all lines that fail to match the pattern.
|
44
|
+
- `-x` Only match entire lines, instead of lines that contain a match.
|
45
|
+
|
46
|
+
If we run `grep -n "hello" input.txt`, the `-n` flag will require the matching
|
47
|
+
lines to be prefixed with its line number:
|
48
|
+
|
49
|
+
```text
|
50
|
+
1:hello
|
51
|
+
3:hello again
|
52
|
+
```
|
53
|
+
|
54
|
+
And if we run `grep -i "HELLO" input.txt`, we'll do a case-insensitive match,
|
55
|
+
and the output will be:
|
56
|
+
|
57
|
+
```text
|
58
|
+
hello
|
59
|
+
hello again
|
60
|
+
```
|
61
|
+
|
62
|
+
The `grep` command should support multiple flags at once.
|
63
|
+
|
64
|
+
For example, running `grep -l -v "hello" file1.txt file2.txt` should
|
65
|
+
print the names of files that do not contain the string "hello".
|
66
|
+
|
67
|
+
# Java Tips
|
68
|
+
|
69
|
+
Since this exercise has difficulty 5 it doesn't come with any starter implementation.
|
70
|
+
This is so that you get to practice creating classes and methods which is an important part of programming in Java.
|
71
|
+
It does mean that when you first try to run the tests, they won't compile.
|
72
|
+
They will give you an error similar to:
|
73
|
+
```
|
74
|
+
path-to-exercism-dir\exercism\java\name-of-exercise\src\test\java\ExerciseClassNameTest.java:14: error: cannot find symbol
|
75
|
+
ExerciseClassName exerciseClassName = new ExerciseClassName();
|
76
|
+
^
|
77
|
+
symbol: class ExerciseClassName
|
78
|
+
location: class ExerciseClassNameTest
|
79
|
+
```
|
80
|
+
This error occurs because the test refers to a class that hasn't been created yet (`ExerciseClassName`).
|
81
|
+
To resolve the error you need to add a file matching the class name in the error to the `src/main/java` directory.
|
82
|
+
For example, for the error above you would add a file called `ExerciseClassName.java`.
|
83
|
+
|
84
|
+
When you try to run the tests again you will get slightly different errors.
|
85
|
+
You might get an error similar to:
|
86
|
+
```
|
87
|
+
constructor ExerciseClassName in class ExerciseClassName cannot be applied to given types;
|
88
|
+
ExerciseClassName exerciseClassName = new ExerciseClassName("some argument");
|
89
|
+
^
|
90
|
+
required: no arguments
|
91
|
+
found: String
|
92
|
+
reason: actual and formal argument lists differ in length
|
93
|
+
```
|
94
|
+
This error means that you need to add a [constructor](https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html) to your new class.
|
95
|
+
If you don't add a constructor, Java will add a default one for you.
|
96
|
+
This default constructor takes no arguments.
|
97
|
+
So if the tests expect your class to have a constructor which takes arguments, then you need to create this constructor yourself.
|
98
|
+
In the example above you could add:
|
99
|
+
```
|
100
|
+
ExerciseClassName(String input) {
|
101
|
+
|
102
|
+
}
|
103
|
+
```
|
104
|
+
That should make the error go away, though you might need to add some more code to your constructor to make the test pass!
|
105
|
+
|
106
|
+
You might also get an error similar to:
|
107
|
+
```
|
108
|
+
error: cannot find symbol
|
109
|
+
assertEquals(expectedOutput, exerciseClassName.someMethod());
|
110
|
+
^
|
111
|
+
symbol: method someMethod()
|
112
|
+
location: variable exerciseClassName of type ExerciseClassName
|
113
|
+
```
|
114
|
+
This error means that you need to add a method called `someMethod` to your new class.
|
115
|
+
In the example above you would add:
|
116
|
+
```
|
117
|
+
String someMethod() {
|
118
|
+
return "";
|
119
|
+
}
|
120
|
+
```
|
121
|
+
Make sure the return type matches what the test is expecting.
|
122
|
+
You can find out which return type it should have by looking at the type of object it's being compared to in the tests.
|
123
|
+
Or you could set your method to return some random type (e.g. `void`), and run the tests again.
|
124
|
+
The new error should tell you which type it's expecting.
|
125
|
+
|
126
|
+
After having resolved these errors you should be ready to start making the tests pass!
|
127
|
+
|
128
|
+
|
129
|
+
# Running the tests
|
130
|
+
|
131
|
+
You can run all the tests for an exercise by entering
|
132
|
+
|
133
|
+
```sh
|
134
|
+
$ gradle test
|
135
|
+
```
|
136
|
+
|
137
|
+
in your terminal.
|
138
|
+
|
139
|
+
## Source
|
140
|
+
|
141
|
+
Conversation with Nate Foster. [http://www.cs.cornell.edu/Courses/cs3110/2014sp/hw/0/ps0.pdf](http://www.cs.cornell.edu/Courses/cs3110/2014sp/hw/0/ps0.pdf)
|
142
|
+
|
143
|
+
## Submitting Incomplete Solutions
|
144
|
+
|
145
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|