Przeglądaj źródła

largest-series-product: add to track (#173)

* largest-series-product: add to track

* Add note to largest-series-product tests about JUnit Rules
John Ryan 9 lat temu
rodzic
commit
d6770852a8

+ 7
- 1
config.json Wyświetl plik

@@ -43,7 +43,8 @@
43 43
     "nth-prime",
44 44
     "pascals-triangle",
45 45
     "beer-song",
46
-    "difference-of-squares"
46
+    "difference-of-squares",
47
+    "largest-series-product"
47 48
   ],
48 49
   "exercises": [
49 50
     {
@@ -245,6 +246,11 @@
245 246
       "slug": "difference-of-squares",
246 247
       "difficulty": 1,
247 248
       "topics": []
249
+    },
250
+    {
251
+      "slug": "largest-series-product",
252
+      "difficulty": 1,
253
+      "topics": []
248 254
     }
249 255
   ],
250 256
   "deprecated": [

+ 17
- 0
exercises/largest-series-product/build.gradle Wyświetl plik

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

+ 56
- 0
exercises/largest-series-product/src/example/java/LargestSeriesProductCalculator.java Wyświetl plik

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

+ 5
- 0
exercises/largest-series-product/src/main/java/LargestSeriesProductCalculator.java Wyświetl plik

@@ -0,0 +1,5 @@
1
+public class LargestSeriesProductCalculator {
2
+
3
+
4
+
5
+}

+ 218
- 0
exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java Wyświetl plik

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

+ 1
- 0
exercises/settings.gradle Wyświetl plik

@@ -14,6 +14,7 @@ include 'grade-school'
14 14
 include 'hamming'
15 15
 include 'hexadecimal'
16 16
 include 'hello-world'
17
+include 'largest-series-product'
17 18
 include 'linked-list'
18 19
 include 'luhn'
19 20
 include 'meetup'