 # paulfioravanti's solution

## to Series in the Elm Track

Published at Jul 26 2019 · 0 comments
Instructions
Test suite
Solution

Given a string of digits, output all the contiguous substrings of length `n` in that string in the order that they appear.

For example, the string "49142" has the following 3-digit series:

• "491"
• "914"
• "142"

And the following 4-digit series:

• "4914"
• "9142"

And if you ask for a 6-digit series from a 5-digit string, you deserve whatever you get.

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

## Elm Installation

Refer to the Installing Elm page for information about installing elm.

## Writing the Code

The first time you start an exercise, you'll need to ensure you have the appropriate dependencies installed. Thankfully, Elm makes that easy for you and will install dependencies when you try to run tests or build the code.

Execute the tests with:

``````\$ elm-test
``````

Automatically run tests again when you save changes:

``````\$ elm-test --watch
``````

As you work your way through the test suite, be sure to remove the `skip <|` calls from each test until you get them all passing!

## Source

A subset of the Problem 8 at Project Euler http://projecteuler.net/problem=8

## Submitting Incomplete Solutions

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

### Tests.elm

``````module Tests exposing (tests)

import Expect
import Series exposing (slices)
import Test exposing (..)

tests : Test
tests =
describe "Series"
[ test "slices of one from one" <|
\() ->
Expect.equal (Ok [ [ 1 ] ])
(slices 1 "1")
, skip <|
test "slices of one from two" <|
\() ->
Expect.equal (Ok [ [ 1 ], [ 2 ] ])
(slices 1 "12")
, skip <|
test "slices of two" <|
\() ->
Expect.equal (Ok [ [ 3, 5 ] ])
(slices 2 "35")
, skip <|
test "slices of two overlap" <|
\() ->
Expect.equal (Ok [ [ 9, 1 ], [ 1, 4 ], [ 4, 2 ] ])
(slices 2 "9142")
, skip <|
test "slices can include duplicates" <|
\() ->
Expect.equal (Ok [ [ 7, 7, 7 ], [ 7, 7, 7 ], [ 7, 7, 7 ], [ 7, 7, 7 ] ])
(slices 3 "777777")
, skip <|
test "slices of a long series" <|
\() ->
Expect.equal (Ok [ [ 9, 1, 8, 4, 9 ], [ 1, 8, 4, 9, 3 ], [ 8, 4, 9, 3, 9 ], [ 4, 9, 3, 9, 0 ], [ 9, 3, 9, 0, 4 ], [ 3, 9, 0, 4, 2 ], [ 9, 0, 4, 2, 4 ], [ 0, 4, 2, 4, 3 ] ])
(slices 5 "918493904243")
, skip <|
test "slice length is too large" <|
\() ->
Expect.equal (Err "slice length cannot be greater than series length")
(slices 6 "12345")
, skip <|
test "slice length cannot be zero" <|
\() ->
Expect.equal (Err "slice length cannot be zero")
(slices 0 "12345")
, skip <|
test "slice length cannot be negative" <|
\() ->
Expect.equal (Err "slice length cannot be negative")
(slices -1 "123")
, skip <|
test "empty series is invalid" <|
\() ->
Expect.equal (Err "series cannot be empty")
(slices 1 "")
]``````
``````module Series exposing (slices)

slices : Int -> String -> Result String (List (List Int))
slices size input =
let
length =
String.length input
in
if size == 0 then
Err "slice length cannot be zero"

else if size < 0 then
Err "slice length cannot be negative"

else if length == 0 then
Err "series cannot be empty"

else if size > length then
Err "slice length cannot be greater than series length"

else
input
|> toIntList
|> chunkEvery size
|> Ok

-- PRIVATE

toIntList : String -> List Int
toIntList input =
let
toInt string =
string
|> String.toInt
|> Maybe.withDefault 0
in
input
|> String.split ""
|> List.map toInt

chunkEvery : Int -> List Int -> List (List Int)
chunkEvery size inputList =
if size == List.length inputList then
[ inputList ]

else
let
chunk =
List.take size inputList

step =
1

tail =
List.drop step inputList
in
chunk :: chunkEvery size tail``````