Year 2015 Day 8 Part 2

This commit is contained in:
Nathan McCarty 2025-01-17 13:49:30 -05:00
parent 9a16de8be7
commit ca07f2995e

View file

@ -199,7 +199,7 @@ string = do
pure xs
```
## Running a parser
### Running a parser
Run a parser, with some debug logging, by peeling the parsing effects of of the
type. The order is important here, remember that function composition "runs"
@ -284,6 +284,23 @@ runParser x str = do
lazyRights (Right x :: xs) = x :: lazyRights xs
```
## Escaping characters
This is much more boring the the parsing, we just do simple recursive pattern
matching on the characters of the provided string, escaping `"` and `\`, and
surround the resulting string with quotes.
```idris
escape : String -> String
escape str = "\"\{pack . escape' . unpack $ str}\""
where
escape' : List Char -> List Char
escape' [] = []
escape' ('"' :: xs) = '\\' :: '"' :: escape' xs
escape' ('\\' :: xs) = '\\' :: '\\' :: escape' xs
escape' (x :: xs) = x :: escape' xs
```
## Part Functions
### Part 1
@ -293,7 +310,7 @@ possible failures by sequencing the `List (Maybe String)` into a
`Maybe (List String)`, and the compute the difference in character counts.
```idris
part1 : Eff (PartEff String) (Int, ())
part1 : Eff (PartEff String) (Int, List String)
part1 = do
inputs <- map lines $ askAt "input"
outputs <- traverse (runParser string) inputs
@ -301,11 +318,34 @@ part1 = do
| _ => throw "Some strings failed to parse"
let difference =
sum $ zipWith (\x, y => strLength x - strLength y) inputs outputs
pure (difference, ())
pure (difference, inputs)
```
### Part 2
Map our character escaping function over our input string and compute the
difference in character counts.
Make a little stop along the way to ensure that escape -> parse round trips
without changing the content of the string.
```idris
part2 : List String -> Eff (PartEff String) Int
part2 inputs = do
let outputs = map escape inputs
Just reversed_outputs <- map sequence . traverse (runParser string) $ outputs
| _ => throw "Reversing escaping of the inputs failed"
unless (all id $ zipWith (==) inputs reversed_outputs) $ do
debug . delay . joinBy "\n" . map show . filter (\(x, y, z) => x /= z) $
zip3 inputs outputs reversed_outputs
throw "Parsed outputs were not identical to inputs"
let difference =
sum $ zipWith (\x, y => strLength y - strLength x) inputs outputs
pure difference
```
<!-- idris
public export
day8 : Day
day8 = First 8 part1
day8 = Both 8 part1 part2
-->