Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
Nathan McCarty | 9721602598 | ||
Nathan McCarty | 62510c6755 |
|
@ -36,3 +36,4 @@ solution.
|
|||
- [Day 5](src/Years/Y2015/Day5.md)
|
||||
- [Day 6](src/Years/Y2015/Day6.md)
|
||||
- [Day 7](src/Years/Y2015/Day7.md)
|
||||
- [Day 8](src/Years/Y2015/Day8.md)
|
||||
|
|
|
@ -14,6 +14,7 @@ import Years.Y2015.Day4
|
|||
import Years.Y2015.Day5
|
||||
import Years.Y2015.Day6
|
||||
import Years.Y2015.Day7
|
||||
import Years.Y2015.Day8
|
||||
-->
|
||||
|
||||
# Days
|
||||
|
@ -66,6 +67,12 @@ y2015 = MkYear 2015 [
|
|||
, day7
|
||||
```
|
||||
|
||||
## [Day 8](Y2015/Day8.md)
|
||||
|
||||
```idris
|
||||
, day8
|
||||
```
|
||||
|
||||
```idris
|
||||
]
|
||||
```
|
||||
|
|
176
src/Years/Y2015/Day8.md
Normal file
176
src/Years/Y2015/Day8.md
Normal file
|
@ -0,0 +1,176 @@
|
|||
# Year 2015 Day 8
|
||||
|
||||
<!-- idris
|
||||
module Years.Y2015.Day8
|
||||
|
||||
import Control.Eff
|
||||
|
||||
import Data.Primitives.Interpolation
|
||||
|
||||
import Runner
|
||||
-->
|
||||
|
||||
```idris
|
||||
import Data.String
|
||||
import Data.Vect
|
||||
import Data.Either
|
||||
```
|
||||
|
||||
## Parsing
|
||||
|
||||
Effect alias for a parser
|
||||
|
||||
```idris
|
||||
Parser : List (Type -> Type)
|
||||
Parser =
|
||||
[Choose, State (List Char), Except String]
|
||||
```
|
||||
|
||||
Get the next character from the state, modifying it in place
|
||||
|
||||
```idris
|
||||
getNext : Eff Parser Char
|
||||
getNext = do
|
||||
chars <- get
|
||||
case chars of
|
||||
[] => throw "End of Input"
|
||||
(x :: xs) => do
|
||||
put xs
|
||||
pure x
|
||||
```
|
||||
|
||||
Parse a quote
|
||||
```idris
|
||||
quote : Eff Parser ()
|
||||
quote = do
|
||||
char <- getNext
|
||||
if char == '"'
|
||||
then pure ()
|
||||
else throw "Expected quote, found: \{show char}"
|
||||
```
|
||||
|
||||
Parse a char that's not a quote or an escape character
|
||||
|
||||
```idris
|
||||
normal : Eff Parser Char
|
||||
normal = do
|
||||
char <- getNext
|
||||
if any (char ==) (the (List _) ['\\', '"'])
|
||||
then throw "Tried to parse a special character as normal \{show char}"
|
||||
else pure char
|
||||
```
|
||||
|
||||
Parse a hex digit
|
||||
|
||||
```idris
|
||||
hexDigit : Eff Parser Int
|
||||
hexDigit = do
|
||||
char <- getNext
|
||||
case toLower char of
|
||||
'0' => pure 0x0
|
||||
'1' => pure 0x1
|
||||
'2' => pure 0x2
|
||||
'3' => pure 0x3
|
||||
'4' => pure 0x4
|
||||
'5' => pure 0x5
|
||||
'6' => pure 0x6
|
||||
'7' => pure 0x7
|
||||
'8' => pure 0x8
|
||||
'9' => pure 0x9
|
||||
'a' => pure 0xa
|
||||
'b' => pure 0xb
|
||||
'c' => pure 0xc
|
||||
'd' => pure 0xd
|
||||
'e' => pure 0xe
|
||||
'f' => pure 0xf
|
||||
_ => throw "Invalid hex digit: \{show char}"
|
||||
```
|
||||
|
||||
Parse an escaped character
|
||||
|
||||
```idris
|
||||
escaped : Eff Parser Char
|
||||
escaped = do
|
||||
escape <- getNext
|
||||
if escape == '\\'
|
||||
then do
|
||||
first <- getNext
|
||||
case first of
|
||||
'\\' => pure '\\'
|
||||
'"' => pure '"'
|
||||
'x' => do
|
||||
[x, y] : Vect _ Int <- sequence [hexDigit, hexDigit]
|
||||
-- Fails to compile
|
||||
-- pure . chr $ x * 0x10 + y
|
||||
-- Compiles
|
||||
pure . (const 'a') $ x * 0x10 + y
|
||||
_ => throw "Invalid Escape Character: \{show first}"
|
||||
else throw "Tried to parse non escape as escape \{show escape}"
|
||||
```
|
||||
|
||||
Parse any non-quote character
|
||||
|
||||
```idris
|
||||
character : Eff Parser Char
|
||||
character = oneOfM (the (List _) [escaped, normal])
|
||||
```
|
||||
|
||||
Run a parser until it runs out
|
||||
|
||||
```idris
|
||||
parseMany : Eff Parser t -> Eff Parser (List t)
|
||||
parseMany x = do
|
||||
Just next <- lift $ catch (\_ => pure Nothing) (map Just x)
|
||||
| _ => pure []
|
||||
map (next ::) (parseMany x)
|
||||
```
|
||||
|
||||
Parse any number of non-quote characters
|
||||
|
||||
```idris
|
||||
characters : Eff Parser (List Char)
|
||||
characters = parseMany character
|
||||
```
|
||||
|
||||
Parse a quote delimited string
|
||||
|
||||
```idris
|
||||
parseString : Eff Parser (List Char)
|
||||
parseString = do
|
||||
quote
|
||||
xs <- characters
|
||||
quote
|
||||
pure xs
|
||||
```
|
||||
|
||||
Run a parser
|
||||
|
||||
```idris
|
||||
runParser : Eff Parser t -> String -> Maybe t
|
||||
runParser m str =
|
||||
map fst . head' . rights
|
||||
. extract . runChoose {f = List} . runExcept . runState (unpack str)
|
||||
$ m
|
||||
|
||||
```
|
||||
|
||||
## Part Functions
|
||||
|
||||
### Part 1
|
||||
|
||||
```idris
|
||||
part1 : Eff (PartEff String) (Nat, List (List Char, List Char))
|
||||
part1 = do
|
||||
inputs <- map (lines . trim) $ askAt "input"
|
||||
let outputs = map (map pack . runParser parseString) inputs
|
||||
let pairs = zip inputs outputs
|
||||
let debug_out = joinBy "\n" . map show $ pairs
|
||||
putStrLn debug_out
|
||||
?part1_rhs_1
|
||||
```
|
||||
|
||||
<!-- idris
|
||||
public export
|
||||
day8 : Day
|
||||
day8 = First 8 part1
|
||||
-->
|
Loading…
Reference in a new issue