trackler 2.0.0.5 → 2.0.0.6

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 (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
+ }