# paulfioravanti's solution

## to Largest Series Product in the Elixir Track

Published at Aug 06 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 tests

Execute the tests with:

``````\$ mix test
``````

### Pending tests

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
``````

If you're stuck on something, it may help to look at some of the available resources out there where answers might be found.

## 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.

### largest_series_product_test.exs

``````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
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``````

### test_helper.exs

``````ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)``````
``````defmodule Series do
defguardp span_too_large?(number_string, size)
when size > byte_size(number_string)

defguardp non_zero_size_on_empty_string?(number_string, size)
when size != 0 and number_string == ""

defguardp negative_size_on_non_empty_string?(number_string, size)
when size < 0 and number_string != ""

defguardp invalid?(number_string, size)
when span_too_large?(number_string, size) or
non_zero_size_on_empty_string?(number_string, size) or
negative_size_on_non_empty_string?(number_string, size)

@zero_series_product 1

@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(number_string, size) when invalid?(number_string, size) do
raise ArgumentError
end

def largest_product(_number_string, 0), do: @zero_series_product

def largest_product(number_string, size) do
number_string
|> String.graphemes()
|> Enum.map(&String.to_integer/1)
|> Enum.reduce(0, &compare_products/2)
end

defp compare_products(subseries, acc) do
product = Enum.reduce(subseries, &*/2)
if product > acc, do: product, else: acc
end
end``````