advent/src/Years/Y2015/Day1.md

83 lines
2.2 KiB
Markdown

# [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
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
public export
day1 : Day
day1 = Both 1 part1 part2
-->