Published at Jul 13 2018
·
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.

Execute the tests with:

```
$ elixir largest_series_product_test.exs
```

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

Once you get a test passing, you can unskip the next one by
commenting out the relevant `@tag :pending`

with a `#`

symbol.

For example:

```
# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
```

Or, you can enable all the tests by commenting out the
`ExUnit.configure`

line in the test suite.

```
# ExUnit.configure exclude: :pending, trace: true
```

For more detailed information about the Elixir track, please see the help page.

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

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

```
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
Code.load_file("largest_series_product.exs", __DIR__)
end
ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)
defmodule LargestSeriesProductTest do
use ExUnit.Case
# @tag :pending
test "largest product of 2" do
assert Series.largest_product("0123456789", 2) == 72
end
@tag :pending
test "largest product of a tiny number" do
assert Series.largest_product("12", 2) == 2
end
@tag :pending
test "another tiny number" do
assert Series.largest_product("19", 2) == 9
end
@tag :pending
test "largest product of 2 shuffled" do
assert Series.largest_product("576802143", 2) == 48
end
@tag :pending
test "largest product of 3" do
assert Series.largest_product("0123456789", 3) == 504
end
@tag :pending
test "largest product of 3 shuffled" do
assert Series.largest_product("1027839564", 3) == 270
end
@tag :pending
test "largest product of 5" do
assert Series.largest_product("0123456789", 5) == 15120
end
@tag :pending
test "some big number" do
assert Series.largest_product("73167176531330624919225119674426574742355349194934", 6) ==
23520
end
@tag :pending
test "some other big number" do
assert Series.largest_product("52677741234314237566414902593461595376319419139427", 6) ==
28350
end
@tag :pending
test "number with all zeroes" do
assert Series.largest_product("0000", 2) == 0
end
@tag :pending
test "number where all products are zero" do
assert Series.largest_product("99099", 3) == 0
end
@tag :pending
test "identity with empty string" do
assert Series.largest_product("", 0) == 1
end
@tag :pending
test "identity with non-empty string" do
assert Series.largest_product("123", 0) == 1
end
@tag :pending
test "raises if span is too large" do
assert_raise ArgumentError, fn ->
Series.largest_product("123", 4)
end
end
@tag :pending
test "raises with empty string but non-zero span size" do
assert_raise ArgumentError, fn ->
Series.largest_product("", 1)
end
end
@tag :pending
test "raises with non-empty string and negative span size" do
assert_raise ArgumentError, fn ->
Series.largest_product("1234", -1)
end
end
end
```

```
defmodule Series do
@doc """
Finds the largest product of a given number of consecutive numbers in a given string of numbers.
"""
@spec largest_product(String.t, non_neg_integer) :: non_neg_integer
def largest_product(_ , 0), do: 1
def largest_product(number_string, size) do
if size < 0 || size > String.length(number_string), do: raise ArgumentError
do_largest_product(number_string
|> String.graphemes
|> Enum.map(&String.to_integer/1),
size,
0)
end
# take next N numbers and multiply, rather than divide by the
# oldest and multiply by the next, because there may be zeroes.
defp do_largest_product(list, size, highest) do
cur_numbers = list |> Enum.take(size)
if length(cur_numbers) == size do
do_largest_product(tl(list),
size,
Enum.max([highest,
cur_numbers |> Enum.reduce(&*/2)]))
else
highest
end
end
end
```

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

- What compromises have been made?
- Are there new concepts here that you could read more about to improve your understanding?

Level up your programming skills with 3,387 exercises across 50 languages, and insightful discussion with our volunteer team of welcoming mentors.
Exercism is
**100% free forever**.

## Community comments