module Day10 where import Data.Maybe import Data.List (sort) import Control.Monad (foldM) closing :: Char -> Maybe Char closing '(' = Just ')' closing '[' = Just ']' closing '{' = Just '}' closing '<' = Just '>' closing _ = Nothing score :: Char -> Maybe Int score ')' = Just 3 score ']' = Just 57 score '}' = Just 1197 score '>' = Just 25137 score _ = Nothing closingScore :: Char -> Int closingScore ')' = 1 closingScore ']' = 2 closingScore '}' = 3 closingScore '>' = 4 calcScore :: String -> Int calcScore xs = foldr (\char score -> score*5 + closingScore char) 0 (reverse xs) getInvalidChar :: [Char] -> String -> Char getInvalidChar _ [] = ' ' getInvalidChar st (x:xs) | x `elem` "([{<" = getInvalidChar (x:st) xs | otherwise = if Just x == (listToMaybe st >>= closing) then getInvalidChar (tail st) xs else x getCompletionString :: [Char] -> String -> String getCompletionString st [] = map (fromJust . closing) st getCompletionString st (x:xs) | x `elem` "([{<" = getCompletionString (x:st) xs | otherwise = if Just x == (listToMaybe st >>= closing) then getCompletionString (tail st) xs else "" main :: IO () main = do input <- lines <$> getContents putStr "part 1: " let chars = mapMaybe (score . getInvalidChar []) input print $ sum chars putStr "part 2: " let compls = filter (> 0) $ map (calcScore . getCompletionString []) input print $ sort compls !! (length compls `div` 2)