-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.hs
74 lines (62 loc) · 1.8 KB
/
run.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
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeApplications #-}
import AoC
import AoC.Grid
import Control.Applicative
import Data.Bifunctor
import Data.Foldable
import Data.List
import Data.Maybe
import Data.Ord
data Error = Incomplete String
| Corrupt Char Char
| InputLeft String
deriving (Show, Eq)
open = "(<[{"
close = \case '(' -> ')'
'<' -> '>'
'[' -> ']'
'{' -> '}'
parser :: String -> Either Error ()
parser = go []
where go st xs = case (st, xs) of
(_, x:xs')
| x `elem` open -> go (x:st) xs' -- new open, push to stack
([], _:_) -> Left (InputLeft xs) -- close, but no stack!
(s:st', x:xs')
| close s == x -> go st' xs' -- close matches stack, pop
| otherwise -> Left (Corrupt (close s) x) -- corrupt!
([], []) -> Right () -- done!
(st, []) -> Left (Incomplete (map close st)) -- parts left to consume!
charScore1 = \case ')' -> 3
']' -> 57
'}' -> 1197
'>' -> 25137
score1 = \case Left (Corrupt _ c) -> charScore1 c
_ -> 0
charScore2 = \case ')' -> 1
']' -> 2
'}' -> 3
'>' -> 4
score2 =
\case Left (Incomplete st) ->
foldl' (\s c -> s * 5 + c) 0 (map charScore2 st)
_ -> 0
part1 =
sum
. map score1
. map parser
part2 =
round
. median
. filter (> 0)
. map score2
. map parser
main = main' "input.txt"
exampleMain = main' "example.txt"
main' file = do
input <- lines <$> readFile file
print (part1 input)
print (part2 input)