# artemkorsakov's solution

## to Largest Series Product in the Java Track

Published at Feb 07 2019 · 0 comments
Instructions
Test suite
Solution

Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.

For example, for the input `'1027839564'`, the largest product for a series of 3 digits is 270 (9 * 5 * 6), and the largest product for a series of 5 digits is 7560 (7 * 8 * 3 * 9 * 5).

Note that these series are only required to occupy adjacent positions in the input; the digits need not be numerically consecutive.

For the input `'73167176531330624919225119674426574742355349194934'`, the largest product for a series of 6 digits is 23520.

# Running the tests

You can run all the tests for an exercise by entering

``````\$ gradle test
``````

## Source

A variation on Problem 8 at Project Euler http://projecteuler.net/problem=8

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### LargestSeriesProductCalculatorTest.java

``````import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.junit.Assert.assertEquals;

public class LargestSeriesProductCalculatorTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void testCorrectlyCalculatesLargestProductWhenSeriesLengthEqualsStringToSearchLength() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("29");
long expectedProduct = 18;

long actualProduct = calculator.calculateLargestProductForSeriesLength(2);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersInOrder() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
long expectedProduct = 72;

long actualProduct = calculator.calculateLargestProductForSeriesLength(2);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersNotInOrder() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("576802143");
long expectedProduct = 48;

long actualProduct = calculator.calculateLargestProductForSeriesLength(2);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersInOrder() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
long expectedProduct = 504;

long actualProduct = calculator.calculateLargestProductForSeriesLength(3);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersNotInOrder() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("1027839564");
long expectedProduct = 270;

long actualProduct = calculator.calculateLargestProductForSeriesLength(3);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductOfLengthFiveWithNumbersInOrder() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
long expectedProduct = 15120;

long actualProduct = calculator.calculateLargestProductForSeriesLength(5);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductInLongStringToSearchV1() {
LargestSeriesProductCalculator calculator
= new LargestSeriesProductCalculator("73167176531330624919225119674426574742355349194934");

long expectedProduct = 23520;

long actualProduct = calculator.calculateLargestProductForSeriesLength(6);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductOfZeroIfAllDigitsAreZeroes() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0000");
long expectedProduct = 0;

long actualProduct = calculator.calculateLargestProductForSeriesLength(2);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductOfZeroIfAllSeriesOfGivenLengthContainZero() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("99099");
long expectedProduct = 0;

long actualProduct = calculator.calculateLargestProductForSeriesLength(3);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testSeriesLengthLongerThanLengthOfStringToTestIsRejected() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage(
"Series length must be less than or equal to the length of the string to search.");

calculator.calculateLargestProductForSeriesLength(4);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductOfLength0ForEmptyStringToSearch() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");
long expectedProduct = 1;

long actualProduct = calculator.calculateLargestProductForSeriesLength(0);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testCorrectlyCalculatesLargestProductOfLength0ForNonEmptyStringToSearch() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");
long expectedProduct = 1;

long actualProduct = calculator.calculateLargestProductForSeriesLength(0);

assertEquals(expectedProduct, actualProduct);
}

@Ignore("Remove to run test")
@Test
public void testEmptyStringToSearchAndSeriesOfNonZeroLengthIsRejected() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage(
"Series length must be less than or equal to the length of the string to search.");

calculator.calculateLargestProductForSeriesLength(1);
}

@Ignore("Remove to run test")
@Test
public void testStringToSearchContainingNonDigitCharacterIsRejected() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("String to search may only contain digits.");

new LargestSeriesProductCalculator("1234a5");
}

@Ignore("Remove to run test")
@Test
public void testNegativeSeriesLengthIsRejected() {
LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("12345");

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Series length must be non-negative.");

calculator.calculateLargestProductForSeriesLength(-1);
}

}``````
``````import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class LargestSeriesProductCalculator {
private String inputNumber;

LargestSeriesProductCalculator(String inputNumber) {
checkDigit(inputNumber);
this.inputNumber = inputNumber;
}

long calculateLargestProductForSeriesLength(int numberOfDigits) {
checkNumberOfDigits(numberOfDigits);
if (numberOfDigits == 0) {
return 1;
}

long theLargestProduct = 0;
for (int i = 0; i <= inputNumber.length() - numberOfDigits; i++) {
long product = getProduct(inputNumber.substring(i, i + numberOfDigits));
if (product > theLargestProduct) {
theLargestProduct = product;
}
}

return theLargestProduct;
}

private long getProduct(String inputNumber) {
return Arrays.stream(inputNumber.split("")).mapToLong(Integer::parseInt).reduce((s1, s2) -> s1 * s2).orElse(0);
}

private void checkDigit(String inputNumber) {
Pattern p = Pattern.compile("^\\d*\$");
Matcher m = p.matcher(inputNumber);
if (m.matches()) {
return;
}
throw new IllegalArgumentException("String to search may only contain digits.");
}

private void checkNumberOfDigits(int numberOfDigits) {
if (numberOfDigits < 0) {
throw new IllegalArgumentException("Series length must be non-negative.");
}
if (inputNumber.length() < numberOfDigits) {
throw new IllegalArgumentException("Series length must be less than or equal to the length of the string to search.");
}
}
}``````