Skip to content

Commit

Permalink
Solution for largest series product
Browse files Browse the repository at this point in the history
  • Loading branch information
sirius248 committed Oct 2, 2015
1 parent 5717cb6 commit 4209f6e
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
22 changes: 22 additions & 0 deletions largest-series-product/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Largest Series Product

Write a program that, when given a string of digits, can calculate the largest product for a series of consecutive digits of length n.

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

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

## Running tests

```bash
$ elixir bob_test.exs
```

(Replace `bob_test.exs` with the name of the test file.)

## Source

A variation on Problem 8 at Project Euler [view source](http://projecteuler.net/problem=8)
46 changes: 46 additions & 0 deletions largest-series-product/largest_series_product.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
defmodule Series do

@doc """
Splits up the given string of numbers into an array of integers.
"""
@spec digits(String.t) :: [non_neg_integer]
def digits(number_string) do
number_string |> String.codepoints
|> Enum.map(&(elem(Integer.parse(&1), 0)))
end

@doc """
Generates sublists of a given size from a given string of numbers.
"""
@spec slices(String.t, non_neg_integer) :: [list(non_neg_integer)]
def slices(number_string, size) do
guard = String.length(number_string) - size

list = number_string |> digits |> Enum.with_index

list |> Enum.map(fn(x) ->
if elem(x, 1) <= guard do
[elem(x, 0)] ++ ((1..(size-1)) |> Enum.map(fn (y) ->
elem(Enum.at(list, elem(x, 1) + y), 0)
end))
end
end)
|> Enum.take(guard+1)
end

@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) do
if size == 0 do
1
else
number_string |> slices(size)
|> Enum.map(fn(x) ->
x |> Enum.reduce(1, fn(y, acc) -> y * acc end)
end)
|> Enum.max
end
end
end
87 changes: 87 additions & 0 deletions largest-series-product/largest_series_product_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
if System.get_env("EXERCISM_TEST_EXAMPLES") do
Code.load_file("example.exs")
else
Code.load_file("largest_series_product.exs")
end

ExUnit.start

defmodule LargestSeriesProductTest do
use ExUnit.Case, async: false

test "digits" do
assert Series.digits("0123456789") == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
end

test "same digits reversed" do
assert Series.digits("9876543210") == [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
end

test "fewer digits" do
assert Series.digits("87654") == [8, 7, 6, 5, 4]
end

test "some other digits" do
assert Series.digits("936923468") == [9, 3, 6, 9, 2, 3, 4, 6, 8]
end

test "slices of zero" do
assert Series.digits("") == []
end

test "slices of two" do
assert Series.slices("01234", 2) == [[0, 1], [1, 2], [2, 3], [3, 4]]
end

test "other slices of two" do
assert Series.slices("98273463", 2) == [[9, 8], [8, 2], [2, 7], [7, 3], [3, 4], [4, 6], [6, 3]]
end

test "slices of three" do
assert Series.slices("01234", 3) == [[0, 1, 2], [1, 2, 3], [2, 3, 4]]
end

test "other slices of three" do
assert Series.slices("982347", 3) == [[9, 8, 2], [8, 2, 3], [2, 3, 4], [3, 4, 7]]
end

test "largest product of 2" do
assert Series.largest_product("0123456789", 2) == 72
end

test "largest product of a tiny number" do
assert Series.largest_product("12", 2) == 2
end

test "another tiny number" do
assert Series.largest_product("19", 2) == 9
end

test "largest product of 2 shuffled" do
assert Series.largest_product("576802143", 2) == 48
end

test "largest product of 3" do
assert Series.largest_product("0123456789", 3) == 504
end

test "largest product of 3 shuffled" do
assert Series.largest_product("1027839564", 3) == 270
end

test "largest product of 5" do
assert Series.largest_product("0123456789", 5) == 15120
end

test "some big number" do
assert Series.largest_product("73167176531330624919225119674426574742355349194934", 6) == 23520
end

test "some other big number" do
assert Series.largest_product("52677741234314237566414902593461595376319419139427", 6) == 28350
end

test "identity" do
assert Series.largest_product("", 0) == 1
end
end

0 comments on commit 4209f6e

Please sign in to comment.