-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path10b.hs
51 lines (42 loc) · 1.27 KB
/
10b.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
{-# LANGUAGE NoImplicitPrelude #-}
import AOC
import qualified Data.Map as M
main :: IO ()
main = interact f
f :: [String] -> Int
f xs = (\x -> x !! (length x `div` 2)) $ sort $ calculatePoints <$> brackets
where
brackets = mapMaybe (either (const Nothing) Just . parse) xs
parse = runParser p "" ""
calculatePoints :: String -> Int
calculatePoints = foldl' (\acc x -> addPoints x (acc * 5)) 0
where
addPoints ')' = (+) 1
addPoints ']' = (+) 2
addPoints '}' = (+) 3
addPoints '>' = (+) 4
addPoints _ = error "not expected"
p :: Parsec String [Char] [Char]
p = many1 (parseBrackets ('(',')')
<|> parseBrackets ('[',']')
<|> parseBrackets ('<', '>')
<|> parseBrackets ('{','}')) >> getState
parseBrackets :: (Char, Char) -> Parsec String [Char] ()
parseBrackets b@(o, c) = parseOpeningBracket b
>> many p
>> (parseClosingBracket c <|> eof)
parseOpeningBracket :: (Char, Char) -> Parsec String [Char] ()
parseOpeningBracket (o,c) = do
char o
modifyState (c :)
pure ()
parseClosingBracket :: Char -> Parsec String [Char] ()
parseClosingBracket c= do
char c
modifyState (removeFirst c)
pure ()
removeFirst :: Char -> String -> String
removeFirst _ [] = []
removeFirst c1 (c2:cs) = if c1 == c2
then cs
else c2:removeFirst c1 cs