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.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/bash/docs/TESTS.md +1 -1
- data/tracks/bash/exercises/bob/bob_test.sh +2 -0
- data/tracks/bash/exercises/gigasecond/gigasecond_test.sh +2 -0
- data/tracks/bash/exercises/hamming/hamming_test.sh +2 -0
- data/tracks/bash/exercises/hello-world/hello_world_test.sh +2 -0
- data/tracks/bash/exercises/leap/leap_test.sh +2 -0
- data/tracks/bash/exercises/raindrops/raindrops_test.sh +2 -0
- data/tracks/bash/exercises/rna-transcription/rna_transcription_test.sh +2 -0
- data/tracks/c/bin/verify-indent +5 -1
- data/tracks/c/config.json +10 -1
- data/tracks/c/exercises/clock/src/clock.h +1 -1
- data/tracks/c/exercises/largest-series-product/test/test_largest_series_product.c +1 -1
- data/tracks/c/exercises/phone-number/src/example.c +4 -2
- data/tracks/c/exercises/roman-numerals/src/example.c +20 -21
- data/tracks/c/exercises/roman-numerals/src/example.h +1 -1
- data/tracks/c/exercises/roman-numerals/test/test_roman_numerals.c +1 -0
- data/tracks/c/exercises/sum-of-multiples/src/example.c +3 -1
- data/tracks/c/exercises/sum-of-multiples/src/example.h +3 -1
- data/tracks/c/exercises/sum-of-multiples/test/test_sum_of_multiples.c +44 -22
- data/tracks/c/exercises/word-count/makefile +16 -0
- data/tracks/c/exercises/word-count/src/example.c +65 -0
- data/tracks/c/exercises/word-count/src/word_count.h +22 -0
- data/tracks/c/exercises/word-count/test/test_word_count.c +372 -0
- data/tracks/c/exercises/word-count/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/word-count/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/word-count/test/vendor/unity_internals.h +701 -0
- data/tracks/crystal/.gitignore +1 -0
- data/tracks/crystal/Makefile +6 -0
- data/tracks/crystal/README.md +25 -0
- data/tracks/crystal/config.json +10 -2
- data/tracks/crystal/exercises/acronym/spec/acronym_spec.cr +32 -0
- data/tracks/crystal/exercises/acronym/src/example.cr +7 -0
- data/tracks/crystal/exercises/hello-world/spec/hello_world_spec.cr +8 -10
- data/tracks/crystal/exercises/hello-world/src/example.cr +1 -1
- data/tracks/crystal/src/generator/exercises/acronym.cr +34 -0
- data/tracks/crystal/src/generator/exercises/exercise_generator.cr +39 -0
- data/tracks/crystal/src/generator/exercises/exercise_test_case.cr +8 -0
- data/tracks/crystal/src/generator/exercises/hello_world.cr +38 -0
- data/tracks/crystal/src/generator/exercises/templates/example.tt +10 -0
- data/tracks/crystal/src/generator/generate.cr +15 -0
- data/tracks/crystal/src/generator/spec/exercise_generator_spec.cr +27 -0
- data/tracks/crystal/src/generator/spec/exercise_test_case_spec.cr +23 -0
- data/tracks/elixir/exercises/space-age/space_age.exs +1 -1
- data/tracks/elm/config.json +5 -31
- data/tracks/elm/elm-package.json +1 -0
- data/tracks/elm/exercises/bob/BobTests.elm +1 -1
- data/tracks/elm/exercises/run-length-encoding/RunLengthEncoding.elm +5 -0
- data/tracks/elm/exercises/scrabble-score/ScrabbleScore.elm +1 -0
- data/tracks/elm/exercises/scrabble-score/ScrabbleScore.example +32 -0
- data/tracks/elm/exercises/scrabble-score/ScrabbleScoreTests.elm +43 -0
- data/tracks/elm/exercises/scrabble-score/elm-package.json +16 -0
- data/tracks/elm/exercises/scrabble-score/runtests.bat +1 -0
- data/tracks/elm/exercises/scrabble-score/runtests.sh +2 -0
- data/tracks/elm/exercises/sublist/Sublist.elm +5 -0
- data/tracks/fsharp/exercises/sum-of-multiples/SumOfMultiplesTest.fs +6 -1
- data/tracks/haskell/docs/LEARNING.md +11 -2
- data/tracks/haskell/exercises/list-ops/test/Tests.hs +2 -0
- data/tracks/java/config.json +13 -1
- data/tracks/java/exercises/etl/src/test/java/EtlTest.java +101 -55
- data/tracks/java/exercises/hello-world/TUTORIAL.md +1 -1
- data/tracks/java/exercises/largest-series-product/build.gradle +17 -0
- data/tracks/java/exercises/largest-series-product/src/example/java/LargestSeriesProductCalculator.java +56 -0
- data/tracks/java/exercises/largest-series-product/src/main/java/LargestSeriesProductCalculator.java +5 -0
- data/tracks/java/exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java +218 -0
- data/tracks/java/exercises/queen-attack/build.gradle +17 -0
- data/tracks/java/exercises/queen-attack/src/example/java/BoardCoordinate.java +39 -0
- data/tracks/java/exercises/queen-attack/src/example/java/QueenAttackCalculator.java +54 -0
- data/tracks/java/exercises/queen-attack/src/main/java/BoardCoordinate.java +5 -0
- data/tracks/java/exercises/queen-attack/src/main/java/QueenAttackCalculator.java +5 -0
- data/tracks/java/exercises/queen-attack/src/test/java/QueenAttackCalculatorTest.java +135 -0
- data/tracks/java/exercises/settings.gradle +2 -0
- data/tracks/ocaml/exercises/leap/test.ml +17 -6
- data/tracks/rust/_test/check-exercises.sh +5 -0
- data/tracks/swift/docs/TESTS.md +23 -3
- 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
|
6
|
-
|
7
|
-
import
|
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 =
|
18
|
-
|
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
|
-
|
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 =
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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 =
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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 =
|
61
|
-
|
62
|
-
put(
|
63
|
-
put(
|
64
|
-
put(
|
65
|
-
put(
|
66
|
-
put(
|
67
|
-
put(
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
put("
|
76
|
-
|
77
|
-
|
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
|
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,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
|
+
}
|