-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay8.hs
93 lines (77 loc) · 2.07 KB
/
Day8.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
module Day8
( part1
, part2
) where
import Data.Either (fromRight)
import Data.Map as M (Map, elems, empty, insert, lookup,
(!?))
import Data.Maybe (fromMaybe)
import Helpers.Parsers (Parser, alpha, nums)
import Text.Megaparsec (eof, optional, parse, try, (<|>))
import Text.Megaparsec.Char (char, eol, string)
type Memory = Map Register Val
type Register = String
type Val = Int
parseCommand :: Val -> Memory -> Parser (Int, Int)
parseCommand maxVal memory = do
Just register <- alpha
char ' '
op <- inc <|> dec
char ' '
Just v1 <- nums
string " if "
Just ref <- (fromMaybe 0 . (!?) memory <$>) <$> alpha
char ' '
comp <- try le <|> try lt <|> try ge <|> try gt <|> ne <|> eq
char ' '
Just v2 <- nums
optional eol
let curVal = fromMaybe 0 . M.lookup register $ memory
newVal = op curVal v1
newMem
| comp ref v2 = insert register newVal memory
| otherwise = memory
newMax
| comp ref v2 = max maxVal newVal
| otherwise = maxVal
end newMax newMem <|> parseCommand newMax newMem
end :: Val -> Memory -> Parser (Int, Int)
end maxVal memory = do
eof
return (maxVal, maximum . elems $ memory)
inc :: Parser (Int -> Int -> Int)
inc = do
string "inc"
return (+)
dec :: Parser (Int -> Int -> Int)
dec = do
string "dec"
return (-)
lt :: Parser (Int -> Int -> Bool)
lt = do
string "<"
return (<)
le :: Parser (Int -> Int -> Bool)
le = do
string "<="
return (<=)
gt :: Parser (Int -> Int -> Bool)
gt = do
string ">"
return (>)
ge :: Parser (Int -> Int -> Bool)
ge = do
string ">="
return (>=)
eq :: Parser (Int -> Int -> Bool)
eq = do
string "=="
return (==)
ne :: Parser (Int -> Int -> Bool)
ne = do
string "!="
return (/=)
part1 :: Bool -> String -> String
part1 _ = show . snd . fromRight (0, 0) . parse (parseCommand 0 empty) ""
part2 :: Bool -> String -> String
part2 _ = show . fst . fromRight (0, 0) . parse (parseCommand 0 empty) ""