ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# slaymance's solution

## to Largest Series Product in the JavaScript Track

Published at Jun 05 2021 · 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.

## Setup

Go through the setup instructions for Javascript to install the necessary dependencies:

https://exercism.io/tracks/javascript/installation

## Requirements

Please `cd` into exercise directory before running all below commands.

Install assignment dependencies:

``````\$ npm install
``````

## Making the test suite pass

Execute the tests with:

``````\$ npm test
``````

In the test suites all tests but the first have been skipped.

Once you get a test passing, you can enable the next one by changing `xtest` to `test`.

## Submitting Solutions

Once you have a solution ready, you can submit it using:

``````exercism submit largest-series-product.js
``````

## Submitting Incomplete Solutions

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

## Exercise Source Credits

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

### largest-series-product.spec.js

``````import { largestProduct } from './largest-series-product';

describe('Largest Series Product', () => {
test('finds the largest product if span equals length', () => {
expect(largestProduct('29', 2)).toEqual(18);
});

xtest('can find the largest product of 2 with numbers in order', () => {
expect(largestProduct('0123456789', 2)).toEqual(72);
});

xtest('can find the largest product of 2', () => {
expect(largestProduct('576802143', 2)).toEqual(48);
});

xtest('can find the largest product of 3 with numbers in order', () => {
expect(largestProduct('0123456789', 3)).toEqual(504);
});

xtest('can find the largest product of 3', () => {
expect(largestProduct('1027839564', 3)).toEqual(270);
});

xtest('can find the largest product of 5 with numbers in order', () => {
expect(largestProduct('0123456789', 5)).toEqual(15120);
});

xtest('can get the largest product of a big number', () => {
expect(
largestProduct('73167176531330624919225119674426574742355349194934', 6)
).toEqual(23520);
});

xtest('reports zero if the only digits are zero', () => {
expect(largestProduct('0000', 2)).toEqual(0);
});

xtest('reports zero if all spans include zero', () => {
expect(largestProduct('99099', 3)).toEqual(0);
});

xtest('rejects span longer than string length', () => {
expect(() => largestProduct('123', 4)).toThrow(
new Error('Span must be smaller than string length')
);
});

xtest('reports 1 for empty string and empty product (0 span)', () => {
expect(largestProduct('', 0)).toEqual(1);
});

xtest('reports 1 for nonempty string and empty product (0 span)', () => {
expect(largestProduct('123', 0)).toEqual(1);
});

xtest('rejects empty string and nonzero span', () => {
expect(() => largestProduct('', 1)).toThrow(
new Error('Span must be smaller than string length')
);
});

xtest('rejects invalid character in digits', () => {
expect(() => largestProduct('1234a5', 2)).toThrow(
new Error('Digits input must only contain digits')
);
});

xtest('rejects negative span', () => {
expect(() => largestProduct('12345', -1)).toThrow(
new Error('Span must be greater than zero')
);
});
});``````
``````/**
* Check out all my solutions to the Exercism JavaScript track:
* github.com/slaymance/exercism/tree/main/javascript
*/

// Helper functions for clarity
const containsNonDigits = string => /\D/.test(string);
const productBy = array => array.reduce((product, num) => product * num, 1);

/**
* These two functions are taken almost directly from my solution to Series exercise here on exercism
* https://exercism.io/tracks/javascript/exercises/series/solutions/40ab3d8550d345b580e1aa67a1fd08bf
*/
const pullDigits = series => [...series].map(Number);
const digitSpans = (digits, span) => Array.from(Array(digits.length - span + 1), (_, i) => digits.slice(i, i + span));

/**
* My solution uses the experimental pipeline operator which is a TC39 Stage 1 proposal to the JavaScript language. You
* https://github.com/tc39/proposal-pipeline-operator
*
* To run this code you'll need to add the "@babel/plugin-proposal-pipeline-operator" to your dev dependencies and
* include the plugin in your babel.config file (the bigint plugin is already included in the project):
* plugins: ["@babel/plugin-syntax-bigint", ["@babel/plugin-proposal-pipeline-operator", { "proposal": "smart" }]]
*/
export const largestProduct = (series = '', span = 0) => {
if (span > series.length) throw new Error('Span must be smaller than string length');
if (span < 0) throw new Error('Span must be greater than zero');
if (containsNonDigits(series)) throw new Error('Digits input must only contain digits');

return series
|> pullDigits
|> digitSpans(#, span)
|> #.reduce((maxProduct, slice) => Math.max(maxProduct, productBy(slice)), 0);
};``````