# [Year 2015 Day 1](https://adventofcode.com/2015/day/1)

Pretty simple, basic warmup problem, nothing really novel is on display here
except the effectful part computations.

```idris hide
module Years.Y2015.Day1

import Control.Eff

import Runner

%default total
```

## Solver Functions

This one implements the entirety of the logic for part 1, in a simple tail
recursive manner, pattern matching on each character in the input string.

We include a case for a non-paren character for totality's sake, but since we
kinda trust the input here we just don't do anything in that branch.

```idris
trackFloor : (start : Integer) -> (xs : List Char) -> Integer
trackFloor start [] = start
trackFloor start ('(' :: xs) = trackFloor (start + 1) xs
trackFloor start (')' :: xs) = trackFloor (start - 1) xs
trackFloor start (x :: xs) = trackFloor start xs
```

This one is slightly more complicated, ultimately very similar to the above, but
with two accumulators, one for the position in the input string in addition to
the one for the current floor.

```idris
findBasement : (position : Nat) -> (currentFloor : Integer) -> (xs : List Char)
  -> Nat
findBasement position currentFloor [] = position
findBasement position currentFloor ('(' :: xs) =
  findBasement (position + 1) (currentFloor + 1) xs
findBasement position currentFloor (')' :: xs) =
  if currentFloor <= 0
    then position
    else findBasement (position + 1) (currentFloor - 1) xs
findBasement position currentFloor (x :: xs) =
  findBasement (position + 1) currentFloor xs
```

## Part Functions

Both this parts are simple application of one of our solver functions

### Part 1

Very uneventful, the only thing novel here is pulling the input out of the
`ReaderL "input" String`, which will become very boring very quickly.

```idris
part1 : Eff (PartEff String) (Integer, ())
part1 = do
  input <- map unpack $ askAt "input"
  let output = trackFloor 0 input
  pure (output, ())
```

### Part 2

We have to be careful to start the position accumulator at 1, since the problem
specifies that the input string is 1-index.

```idris
part2 : () -> Eff (PartEff String) Nat
part2 x = do
  input <- map unpack $ askAt "input"
  pure $ findBasement 1 0 input
```

```idris hide
public export
day1 : Day
day1 = Both 1 part1 part2
```