trackler 2.0.0.5 → 2.0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/bash/docs/TESTS.md +1 -1
  4. data/tracks/bash/exercises/bob/bob_test.sh +2 -0
  5. data/tracks/bash/exercises/gigasecond/gigasecond_test.sh +2 -0
  6. data/tracks/bash/exercises/hamming/hamming_test.sh +2 -0
  7. data/tracks/bash/exercises/hello-world/hello_world_test.sh +2 -0
  8. data/tracks/bash/exercises/leap/leap_test.sh +2 -0
  9. data/tracks/bash/exercises/raindrops/raindrops_test.sh +2 -0
  10. data/tracks/bash/exercises/rna-transcription/rna_transcription_test.sh +2 -0
  11. data/tracks/c/bin/verify-indent +5 -1
  12. data/tracks/c/config.json +10 -1
  13. data/tracks/c/exercises/clock/src/clock.h +1 -1
  14. data/tracks/c/exercises/largest-series-product/test/test_largest_series_product.c +1 -1
  15. data/tracks/c/exercises/phone-number/src/example.c +4 -2
  16. data/tracks/c/exercises/roman-numerals/src/example.c +20 -21
  17. data/tracks/c/exercises/roman-numerals/src/example.h +1 -1
  18. data/tracks/c/exercises/roman-numerals/test/test_roman_numerals.c +1 -0
  19. data/tracks/c/exercises/sum-of-multiples/src/example.c +3 -1
  20. data/tracks/c/exercises/sum-of-multiples/src/example.h +3 -1
  21. data/tracks/c/exercises/sum-of-multiples/test/test_sum_of_multiples.c +44 -22
  22. data/tracks/c/exercises/word-count/makefile +16 -0
  23. data/tracks/c/exercises/word-count/src/example.c +65 -0
  24. data/tracks/c/exercises/word-count/src/word_count.h +22 -0
  25. data/tracks/c/exercises/word-count/test/test_word_count.c +372 -0
  26. data/tracks/c/exercises/word-count/test/vendor/unity.c +1300 -0
  27. data/tracks/c/exercises/word-count/test/vendor/unity.h +274 -0
  28. data/tracks/c/exercises/word-count/test/vendor/unity_internals.h +701 -0
  29. data/tracks/crystal/.gitignore +1 -0
  30. data/tracks/crystal/Makefile +6 -0
  31. data/tracks/crystal/README.md +25 -0
  32. data/tracks/crystal/config.json +10 -2
  33. data/tracks/crystal/exercises/acronym/spec/acronym_spec.cr +32 -0
  34. data/tracks/crystal/exercises/acronym/src/example.cr +7 -0
  35. data/tracks/crystal/exercises/hello-world/spec/hello_world_spec.cr +8 -10
  36. data/tracks/crystal/exercises/hello-world/src/example.cr +1 -1
  37. data/tracks/crystal/src/generator/exercises/acronym.cr +34 -0
  38. data/tracks/crystal/src/generator/exercises/exercise_generator.cr +39 -0
  39. data/tracks/crystal/src/generator/exercises/exercise_test_case.cr +8 -0
  40. data/tracks/crystal/src/generator/exercises/hello_world.cr +38 -0
  41. data/tracks/crystal/src/generator/exercises/templates/example.tt +10 -0
  42. data/tracks/crystal/src/generator/generate.cr +15 -0
  43. data/tracks/crystal/src/generator/spec/exercise_generator_spec.cr +27 -0
  44. data/tracks/crystal/src/generator/spec/exercise_test_case_spec.cr +23 -0
  45. data/tracks/elixir/exercises/space-age/space_age.exs +1 -1
  46. data/tracks/elm/config.json +5 -31
  47. data/tracks/elm/elm-package.json +1 -0
  48. data/tracks/elm/exercises/bob/BobTests.elm +1 -1
  49. data/tracks/elm/exercises/run-length-encoding/RunLengthEncoding.elm +5 -0
  50. data/tracks/elm/exercises/scrabble-score/ScrabbleScore.elm +1 -0
  51. data/tracks/elm/exercises/scrabble-score/ScrabbleScore.example +32 -0
  52. data/tracks/elm/exercises/scrabble-score/ScrabbleScoreTests.elm +43 -0
  53. data/tracks/elm/exercises/scrabble-score/elm-package.json +16 -0
  54. data/tracks/elm/exercises/scrabble-score/runtests.bat +1 -0
  55. data/tracks/elm/exercises/scrabble-score/runtests.sh +2 -0
  56. data/tracks/elm/exercises/sublist/Sublist.elm +5 -0
  57. data/tracks/fsharp/exercises/sum-of-multiples/SumOfMultiplesTest.fs +6 -1
  58. data/tracks/haskell/docs/LEARNING.md +11 -2
  59. data/tracks/haskell/exercises/list-ops/test/Tests.hs +2 -0
  60. data/tracks/java/config.json +13 -1
  61. data/tracks/java/exercises/etl/src/test/java/EtlTest.java +101 -55
  62. data/tracks/java/exercises/hello-world/TUTORIAL.md +1 -1
  63. data/tracks/java/exercises/largest-series-product/build.gradle +17 -0
  64. data/tracks/java/exercises/largest-series-product/src/example/java/LargestSeriesProductCalculator.java +56 -0
  65. data/tracks/java/exercises/largest-series-product/src/main/java/LargestSeriesProductCalculator.java +5 -0
  66. data/tracks/java/exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java +218 -0
  67. data/tracks/java/exercises/queen-attack/build.gradle +17 -0
  68. data/tracks/java/exercises/queen-attack/src/example/java/BoardCoordinate.java +39 -0
  69. data/tracks/java/exercises/queen-attack/src/example/java/QueenAttackCalculator.java +54 -0
  70. data/tracks/java/exercises/queen-attack/src/main/java/BoardCoordinate.java +5 -0
  71. data/tracks/java/exercises/queen-attack/src/main/java/QueenAttackCalculator.java +5 -0
  72. data/tracks/java/exercises/queen-attack/src/test/java/QueenAttackCalculatorTest.java +135 -0
  73. data/tracks/java/exercises/settings.gradle +2 -0
  74. data/tracks/ocaml/exercises/leap/test.ml +17 -6
  75. data/tracks/rust/_test/check-exercises.sh +5 -0
  76. data/tracks/swift/docs/TESTS.md +23 -3
  77. metadata +35 -2
@@ -1,79 +1,125 @@
1
- import com.google.common.collect.ImmutableMap;
2
1
  import org.junit.Test;
3
- import org.junit.Ignore;
4
2
 
5
- import java.util.Arrays;
6
- import java.util.List;
7
- import java.util.Map;
3
+ import java.util.*;
4
+
5
+ import static org.junit.Assert.assertEquals;
8
6
 
9
- import static org.assertj.core.api.Assertions.assertThat;
10
7
 
11
8
  public class EtlTest {
12
9
  private final Etl etl = new Etl();
13
10
 
14
-
15
11
  @Test
16
12
  public void testTransformOneValue() {
17
- Map<Integer, List<String>> old = ImmutableMap.of(1, Arrays.asList("A"));
18
- Map<String, Integer> expected = ImmutableMap.of("a", 1);
13
+ Map<Integer, List<String>> old = new HashMap<Integer, List<String>>() {
14
+ {
15
+ put(1, Arrays.asList("A"));
16
+ }
17
+ };
18
+ old = Collections.unmodifiableMap(old);
19
+
20
+ Map<String, Integer> expected = new HashMap<String, Integer>() {
21
+ {
22
+ put("a", 1);
23
+ }
24
+ };
25
+ expected = Collections.unmodifiableMap(expected);
19
26
 
20
- assertThat(etl.transform(old)).isEqualTo(expected);
27
+ assertEquals(etl.transform(old), expected);
21
28
  }
22
29
 
23
- @Ignore
24
30
  @Test
25
31
  public void testTransformMoreValues() {
26
- Map<Integer, List<String>> old = ImmutableMap.of(
27
- 1, Arrays.asList("A", "E", "I", "O", "U")
28
- );
29
- Map<String, Integer> expected = ImmutableMap.of(
30
- "a", 1,
31
- "e", 1,
32
- "i", 1,
33
- "o", 1,
34
- "u", 1
35
- );
36
-
37
- assertThat(etl.transform(old)).isEqualTo(expected);
32
+ Map<Integer, List<String>> old = new HashMap<Integer, List<String>>() {
33
+ {
34
+ put(1, Arrays.asList("A", "E", "I", "O", "U"));
35
+ }
36
+ };
37
+ old = Collections.unmodifiableMap(old);
38
+
39
+ Map<String, Integer> expected = new HashMap<String, Integer>() {
40
+ {
41
+ put("a", 1);
42
+ put("e", 1);
43
+ put("i", 1);
44
+ put("o", 1);
45
+ put("u", 1);
46
+ }
47
+ };
48
+ expected = Collections.unmodifiableMap(expected);
49
+
50
+ assertEquals(etl.transform(old), expected);
38
51
  }
39
52
 
40
- @Ignore
41
53
  @Test
42
54
  public void testMoreKeys() {
43
- Map<Integer, List<String>> old = ImmutableMap.of(
44
- 1, Arrays.asList("A", "E"),
45
- 2, Arrays.asList("D", "G")
46
- );
47
- Map<String, Integer> expected = ImmutableMap.of(
48
- "a", 1,
49
- "e", 1,
50
- "d", 2,
51
- "g", 2
52
- );
53
-
54
- assertThat(etl.transform(old)).isEqualTo(expected);
55
+ Map<Integer, List<String>> old = new HashMap<Integer, List<String>>() {
56
+ {
57
+ put(1, Arrays.asList("A", "E"));
58
+ put(2, Arrays.asList("D", "G"));
59
+ }
60
+ };
61
+ old = Collections.unmodifiableMap(old);
62
+
63
+ Map<String, Integer> expected = new HashMap<String, Integer>() {
64
+ {
65
+ put("a", 1);
66
+ put("e", 1);
67
+ put("d", 2);
68
+ put("g", 2);
69
+ }
70
+ };
71
+ expected = Collections.unmodifiableMap(expected);
72
+
73
+ assertEquals(etl.transform(old), expected);
55
74
  }
56
75
 
57
- @Ignore
58
76
  @Test
59
77
  public void testFullDataset() {
60
- Map<Integer, List<String>> old = ImmutableMap.<Integer, List<String>>builder().
61
- put(1, Arrays.asList("A", "E", "I", "O", "U", "L", "N", "R", "S", "T")).
62
- put(2, Arrays.asList("D", "G")).
63
- put(3, Arrays.asList("B", "C", "M", "P")).
64
- put(4, Arrays.asList("F", "H", "V", "W", "Y")).
65
- put(5, Arrays.asList("K")).
66
- put(8, Arrays.asList("J", "X")).
67
- put(10, Arrays.asList("Q", "Z")).
68
- build();
69
- Map<String, Integer> expected = ImmutableMap.<String, Integer>builder().
70
- put("a", 1).put("b", 3).put("c", 3).put("d", 2).put("e", 1).
71
- put("f", 4).put("g", 2).put("h", 4).put("i", 1).put("j", 8).
72
- put("k", 5).put("l", 1).put("m", 3).put("n", 1).put("o", 1).
73
- put("p", 3).put("q", 10).put("r", 1).put("s", 1).put("t", 1).
74
- put("u", 1).put("v", 4).put("w", 4).put("x", 8).put("y", 4).
75
- put("z", 10).build();
76
-
77
- assertThat(etl.transform(old)).isEqualTo(expected);
78
+ Map<Integer, List<String>> old = new HashMap<Integer, List<String>>() {
79
+ {
80
+ put(1, Arrays.asList("A", "E", "I", "O", "U", "L", "N", "R", "S", "T"));
81
+ put(2, Arrays.asList("D", "G"));
82
+ put(3, Arrays.asList("B", "C", "M", "P"));
83
+ put(4, Arrays.asList("F", "H", "V", "W", "Y"));
84
+ put(5, Arrays.asList("K"));
85
+ put(8, Arrays.asList("J", "X"));
86
+ put(10, Arrays.asList("Q", "Z"));
87
+ }
88
+ };
89
+ old = Collections.unmodifiableMap(old);
90
+
91
+ Map<String, Integer> expected = new HashMap<String, Integer>() {
92
+ {
93
+ put("a", 1);
94
+ put("b", 3);
95
+ put("c", 3);
96
+ put("d", 2);
97
+ put("e", 1);
98
+ put("f", 4);
99
+ put("g", 2);
100
+ put("h", 4);
101
+ put("i", 1);
102
+ put("j", 8);
103
+ put("k", 5);
104
+ put("l", 1);
105
+ put("m", 3);
106
+ put("n", 1);
107
+ put("o", 1);
108
+ put("p", 3);
109
+ put("q", 10);
110
+ put("r", 1);
111
+ put("s", 1);
112
+ put("t", 1);
113
+ put("u", 1);
114
+ put("v", 4);
115
+ put("w", 4);
116
+ put("x", 8);
117
+ put("y", 4);
118
+ put("z", 10);
119
+ }
120
+ };
121
+ expected = Collections.unmodifiableMap(expected);
122
+
123
+ assertEquals(etl.transform(old), expected);
78
124
  }
79
125
  }
@@ -419,7 +419,7 @@ for "good" design of software is a big topic. The pursuit of it underlies
419
419
  much of what makes up the more valuable conversations on Exercism.
420
420
 
421
421
  For now, let's just take a quick review of our solution and see if there's
422
- any part of it we'd like to refactor. Refactoring is changing the the way
422
+ any part of it we'd like to refactor. Refactoring is changing the way
423
423
  a bit of code reads without changing what it does.
424
424
 
425
425
  Right now, the details of detecting whether the caller of `hello()` has
@@ -0,0 +1,17 @@
1
+ apply plugin: "java"
2
+ apply plugin: "eclipse"
3
+ apply plugin: "idea"
4
+
5
+ repositories {
6
+ mavenCentral()
7
+ }
8
+
9
+ dependencies {
10
+ testCompile "junit:junit:4.12"
11
+ }
12
+ test {
13
+ testLogging {
14
+ exceptionFormat = 'full'
15
+ events = ["passed", "failed", "skipped"]
16
+ }
17
+ }
@@ -0,0 +1,56 @@
1
+ public final class LargestSeriesProductCalculator {
2
+
3
+ private final String stringToSearch;
4
+
5
+ public LargestSeriesProductCalculator(final String stringToSearch) throws IllegalArgumentException {
6
+ this.stringToSearch = stringToSearch;
7
+ validateStringToSearch();
8
+ }
9
+
10
+ public long calculateLargestProductForSeriesLength(final int seriesLength) throws IllegalArgumentException {
11
+ if (seriesLength < 0) {
12
+ throw new IllegalArgumentException("Series length must be non-negative.");
13
+ } else if (seriesLength == 0) {
14
+ return 1;
15
+ } else if (seriesLength > stringToSearch.length()) {
16
+ throw new IllegalArgumentException(
17
+ "Series length must be less than or equal to the length of the string to search.");
18
+ } else {
19
+ long result = 0;
20
+
21
+ int numberOfSeriesToCheck = stringToSearch.length() - seriesLength + 1;
22
+
23
+ for (int startIndex = 0; startIndex < numberOfSeriesToCheck; startIndex++) {
24
+ /*
25
+ * Note: computing the product of each series fresh each time is not the most efficient solution, but
26
+ * it's the simplest to reason about.
27
+ */
28
+ result = Math.max(result, computeProductOfSeries(startIndex, seriesLength));
29
+ }
30
+
31
+ return result;
32
+ }
33
+ }
34
+
35
+ private void validateStringToSearch() throws IllegalArgumentException {
36
+ if (stringToSearch == null) {
37
+ throw new IllegalArgumentException("String to search must be non-null.");
38
+ } else if (!stringToSearch.chars().allMatch(Character::isDigit)) {
39
+ throw new IllegalArgumentException("String to search may only contains digits.");
40
+ }
41
+ }
42
+
43
+ private long computeProductOfSeries(final int startIndex, final int seriesLength) {
44
+ // The multiplicative identity is 1.
45
+ long result = 1;
46
+
47
+ final int endIndex = startIndex + seriesLength - 1;
48
+
49
+ for (int characterIndex = startIndex; characterIndex <= endIndex; characterIndex++) {
50
+ result = result * Character.getNumericValue(stringToSearch.charAt(characterIndex));
51
+ }
52
+
53
+ return result;
54
+ }
55
+
56
+ }
@@ -0,0 +1,5 @@
1
+ public class LargestSeriesProductCalculator {
2
+
3
+
4
+
5
+ }
@@ -0,0 +1,218 @@
1
+ import org.junit.Ignore;
2
+ import org.junit.Rule;
3
+ import org.junit.Test;
4
+ import org.junit.rules.ExpectedException;
5
+
6
+ import static org.junit.Assert.assertEquals;
7
+
8
+ public final class LargestSeriesProductCalculatorTest {
9
+
10
+ /*
11
+ * See https://github.com/junit-team/junit4/wiki/Rules for information on JUnit Rules in general and
12
+ * ExpectedExceptions in particular.
13
+ */
14
+ @Rule
15
+ public ExpectedException expectedException = ExpectedException.none();
16
+
17
+ @Test
18
+ public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersInOrder() {
19
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
20
+ final long expectedProduct = 72;
21
+
22
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
23
+
24
+ assertEquals(expectedProduct, actualProduct);
25
+ }
26
+
27
+ @Ignore
28
+ @Test
29
+ public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersNotInOrder() {
30
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("576802143");
31
+ final long expectedProduct = 48;
32
+
33
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
34
+
35
+ assertEquals(expectedProduct, actualProduct);
36
+ }
37
+
38
+ @Ignore
39
+ @Test
40
+ public void testCorrectlyCalculatesLargestProductWhenSeriesLengthEqualsStringToSearchLength() {
41
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("29");
42
+ final long expectedProduct = 18;
43
+
44
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
45
+
46
+ assertEquals(expectedProduct, actualProduct);
47
+ }
48
+
49
+ @Ignore
50
+ @Test
51
+ public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersInOrder() {
52
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
53
+ final long expectedProduct = 504;
54
+
55
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(3);
56
+
57
+ assertEquals(expectedProduct, actualProduct);
58
+ }
59
+
60
+ @Ignore
61
+ @Test
62
+ public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersNotInOrder() {
63
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("1027839564");
64
+ final long expectedProduct = 270;
65
+
66
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(3);
67
+
68
+ assertEquals(expectedProduct, actualProduct);
69
+ }
70
+
71
+ @Ignore
72
+ @Test
73
+ public void testCorrectlyCalculatesLargestProductOfLengthFiveWithNumbersInOrder() {
74
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
75
+ final long expectedProduct = 15120;
76
+
77
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(5);
78
+
79
+ assertEquals(expectedProduct, actualProduct);
80
+ }
81
+
82
+ @Ignore
83
+ @Test
84
+ public void testCorrectlyCalculatesLargestProductInLongStringToSearchV1() {
85
+ final LargestSeriesProductCalculator calculator
86
+ = new LargestSeriesProductCalculator("73167176531330624919225119674426574742355349194934");
87
+
88
+ final long expectedProduct = 23520;
89
+
90
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(6);
91
+
92
+ assertEquals(expectedProduct, actualProduct);
93
+ }
94
+
95
+ @Ignore
96
+ @Test
97
+ public void testCorrectlyCalculatesLargestProductInLongStringToSearchV2() {
98
+ final LargestSeriesProductCalculator calculator
99
+ = new LargestSeriesProductCalculator("52677741234314237566414902593461595376319419139427");
100
+
101
+ final long expectedProduct = 28350;
102
+
103
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(6);
104
+
105
+ assertEquals(expectedProduct, actualProduct);
106
+ }
107
+
108
+ @Ignore
109
+ @Test
110
+ public void testCorrectlyCalculatesLargestProductInLongStringToSearchFromProjectEuler() {
111
+ final LargestSeriesProductCalculator calculator
112
+ = new LargestSeriesProductCalculator("7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450");
113
+
114
+ final long expectedProduct = 23514624000L;
115
+
116
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(13);
117
+
118
+ assertEquals(expectedProduct, actualProduct);
119
+ }
120
+
121
+ @Ignore
122
+ @Test
123
+ public void testCorrectlyCalculatesLargestProductOfZeroIfAllDigitsAreZeroes() {
124
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0000");
125
+ final long expectedProduct = 0;
126
+
127
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
128
+
129
+ assertEquals(expectedProduct, actualProduct);
130
+ }
131
+
132
+ @Ignore
133
+ @Test
134
+ public void testCorrectlyCalculatesLargestProductOfZeroIfAllSeriesOfGivenLengthContainZero() {
135
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("99099");
136
+ final long expectedProduct = 0;
137
+
138
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(3);
139
+
140
+ assertEquals(expectedProduct, actualProduct);
141
+ }
142
+
143
+ @Ignore
144
+ @Test
145
+ public void testSeriesLengthLongerThanLengthOfStringToTestIsRejected() {
146
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");
147
+
148
+ expectedException.expect(IllegalArgumentException.class);
149
+ expectedException.expectMessage(
150
+ "Series length must be less than or equal to the length of the string to search.");
151
+
152
+ calculator.calculateLargestProductForSeriesLength(4);
153
+ }
154
+
155
+ @Ignore
156
+ @Test
157
+ public void testCorrectlyCalculatesLargestProductOfLength0ForEmptyStringToSearch() {
158
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");
159
+ final long expectedProduct = 1;
160
+
161
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(0);
162
+
163
+ assertEquals(expectedProduct, actualProduct);
164
+ }
165
+
166
+ @Ignore
167
+ @Test
168
+ public void testCorrectlyCalculatesLargestProductOfLength0ForNonEmptyStringToSearch() {
169
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");
170
+ final long expectedProduct = 1;
171
+
172
+ final long actualProduct = calculator.calculateLargestProductForSeriesLength(0);
173
+
174
+ assertEquals(expectedProduct, actualProduct);
175
+ }
176
+
177
+ @Ignore
178
+ @Test
179
+ public void testEmptyStringToSearchAndSeriesOfNonZeroLengthIsRejected() {
180
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");
181
+
182
+ expectedException.expect(IllegalArgumentException.class);
183
+ expectedException.expectMessage(
184
+ "Series length must be less than or equal to the length of the string to search.");
185
+
186
+ calculator.calculateLargestProductForSeriesLength(1);
187
+ }
188
+
189
+ @Ignore
190
+ @Test
191
+ public void testStringToSearchContainingNonDigitCharacterIsRejected() {
192
+ expectedException.expect(IllegalArgumentException.class);
193
+ expectedException.expectMessage("String to search may only contains digits.");
194
+
195
+ new LargestSeriesProductCalculator("1234a5");
196
+ }
197
+
198
+ @Ignore
199
+ @Test
200
+ public void testNegativeSeriesLengthIsRejected() {
201
+ final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("12345");
202
+
203
+ expectedException.expect(IllegalArgumentException.class);
204
+ expectedException.expectMessage("Series length must be non-negative.");
205
+
206
+ calculator.calculateLargestProductForSeriesLength(-1);
207
+ }
208
+
209
+ @Ignore
210
+ @Test
211
+ public void testNullStringToSearchIsRejected() {
212
+ expectedException.expect(IllegalArgumentException.class);
213
+ expectedException.expectMessage("String to search must be non-null.");
214
+
215
+ new LargestSeriesProductCalculator(null);
216
+ }
217
+
218
+ }
@@ -0,0 +1,17 @@
1
+ apply plugin: "java"
2
+ apply plugin: "eclipse"
3
+ apply plugin: "idea"
4
+
5
+ repositories {
6
+ mavenCentral()
7
+ }
8
+
9
+ dependencies {
10
+ testCompile "junit:junit:4.12"
11
+ }
12
+ test {
13
+ testLogging {
14
+ exceptionFormat = 'full'
15
+ events = ["passed", "failed", "skipped"]
16
+ }
17
+ }
@@ -0,0 +1,39 @@
1
+ public final class BoardCoordinate {
2
+
3
+ private final int rank;
4
+
5
+ private final int file;
6
+
7
+ public BoardCoordinate(final int rank, final int file) throws IllegalArgumentException {
8
+ this.rank = rank;
9
+ this.file = file;
10
+
11
+ validateInputs();
12
+ }
13
+
14
+ public int getRank() {
15
+ return rank;
16
+ }
17
+
18
+ public int getFile() {
19
+ return file;
20
+ }
21
+
22
+ private void validateInputs() throws IllegalArgumentException {
23
+ validateCoordinateComponent(rank, "rank");
24
+ validateCoordinateComponent(file, "file");
25
+ }
26
+
27
+ private void validateCoordinateComponent(final int value, final String componentName)
28
+ throws IllegalArgumentException {
29
+
30
+ if (value < 0) {
31
+ throw new IllegalArgumentException("Coordinate must have positive " + componentName + ".");
32
+ }
33
+
34
+ if (value > 7) {
35
+ throw new IllegalArgumentException("Coordinate must have " + componentName + " <= 7.");
36
+ }
37
+ }
38
+
39
+ }
@@ -0,0 +1,54 @@
1
+ public final class QueenAttackCalculator {
2
+
3
+ private final BoardCoordinate whiteQueenCoordinate;
4
+
5
+ private final BoardCoordinate blackQueenCoordinate;
6
+
7
+ public QueenAttackCalculator(final BoardCoordinate whiteQueenCoordinate, final BoardCoordinate blackQueenCoordinate)
8
+ throws IllegalArgumentException {
9
+
10
+ this.whiteQueenCoordinate = whiteQueenCoordinate;
11
+ this.blackQueenCoordinate = blackQueenCoordinate;
12
+
13
+ validateInputs();
14
+ }
15
+
16
+ public boolean canQueensAttackOneAnother() {
17
+ return queensShareFile() || queensShareRank() || queensShareDiagonal();
18
+ }
19
+
20
+ private void validateInputs() throws IllegalArgumentException {
21
+ if (whiteQueenCoordinate == null || blackQueenCoordinate == null) {
22
+ throw new IllegalArgumentException("You must supply valid board coordinates for both Queens.");
23
+ }
24
+
25
+ if (queensShareBoardCoordinate()) {
26
+ throw new IllegalArgumentException("Queens may not occupy the same board coordinate.");
27
+ }
28
+ }
29
+
30
+ private boolean queensShareRank() {
31
+ return differenceBetweenRanks() == 0;
32
+ }
33
+
34
+ private boolean queensShareFile() {
35
+ return differenceBetweenFiles() == 0;
36
+ }
37
+
38
+ private boolean queensShareBoardCoordinate() {
39
+ return queensShareRank() && queensShareFile();
40
+ }
41
+
42
+ private boolean queensShareDiagonal() {
43
+ return differenceBetweenRanks() == differenceBetweenFiles();
44
+ }
45
+
46
+ private int differenceBetweenRanks() {
47
+ return Math.abs(whiteQueenCoordinate.getRank() - blackQueenCoordinate.getRank());
48
+ }
49
+
50
+ private int differenceBetweenFiles() {
51
+ return Math.abs(whiteQueenCoordinate.getFile() - blackQueenCoordinate.getFile());
52
+ }
53
+
54
+ }
@@ -0,0 +1,5 @@
1
+ public final class BoardCoordinate {
2
+
3
+
4
+
5
+ }
@@ -0,0 +1,5 @@
1
+ public final class QueenAttackCalculator {
2
+
3
+
4
+
5
+ }