aoc-2021/day10/first.hs

46 lines
1.1 KiB
Haskell

type Parser = Char -> Maybe Char
parseChar :: Char -> Parser
parseChar c x
| c == x = Nothing
| otherwise = Just x
mapOpenClose :: Char -> Char
mapOpenClose c = case c of
'(' -> ')'
'[' -> ']'
'{' -> '}'
'<' -> '>'
_ -> error "not element in map"
score :: Char -> Integer
score c = case c of
')' -> 3
']' -> 57
'}' -> 1197
'>' -> 25137
_ -> 0
openDelim c = (c=='(') || (c=='[') || (c=='{') || (c=='<')
closingDelim c = (c==')') || (c==']') || (c=='}') || (c=='>')
-- Keep stack of parse functions. Apply the top one on any closing delimeter,
-- check for Just x.
parseLine :: [Parser] -> String -> Char
parseLine _ [] = ' '
parseLine parsers (c:str)
| openDelim c = parseLine ((parseChar $ mapOpenClose c):parsers) str
| closingDelim c = case p c of
Just _ -> c
Nothing -> parseLine (tail parsers) str
where p = head parsers
solution :: [String] -> Integer
solution = foldr (+) 0
. map score
. filter (/=' ') -- painful, I blame Haskell's lack of proper sum types
. (map $ parseLine [])
main = interact $ show . solution . lines