-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day9.hs
53 lines (43 loc) · 1.28 KB
/
Day9.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
module Day9
( part1
, part2
) where
import Data.Either (fromRight)
import Helpers.Parsers (Parser)
import Text.Megaparsec (manyTill, optional, parse, takeWhile1P,
try, (<|>))
import Text.Megaparsec.Char (char, printChar)
data Group
= Group Int [Group]
| Garbage Int
deriving (Show)
parseGroup :: Int -> Parser Group
parseGroup depth = do
char '{'
contents <- manyTill (parseGroup (depth + 1) <|> parseGarbage) (char '}')
optional . char $ ','
return . Group depth $ contents
parseGarbage :: Parser Group
parseGarbage = do
char '<'
count <- manyTill (cancel <|> garb) (char '>')
optional . char $ ','
return . Garbage . sum $ count
cancel :: Parser Int
cancel = do
char '!'
printChar
return 0
garb :: Parser Int
garb = do
length <$> takeWhile1P Nothing (`notElem` "!>")
score1 :: Group -> Int
score1 (Garbage _) = 0
score1 (Group s g) = (+ s) . sum . map score1 $ g
score2 :: Group -> Int
score2 (Garbage g) = g
score2 (Group _ g) = sum . map score2 $ g
part1 :: Bool -> String -> String
part1 _ = show . score1 . fromRight (Garbage 0) . parse (parseGroup 1) ""
part2 :: Bool -> String -> String
part2 _ = show . score2 . fromRight (Garbage 0) . parse (parseGroup 1) ""