import Data.List (foldl', sort) main :: IO () main = do input <- getContents let code = lines input (putStrLn . show . solution1) code (putStrLn . show . solution2) code solution1 :: [String] -> Int solution1 = sum . map charScore . map (head . fst . resolveChunks) where charScore :: Char -> Int charScore ')' = 3 charScore ']' = 57 charScore '}' = 1197 charScore '>' = 25137 charScore _ = 0 solution2 :: [String] -> Int solution2 = middle . sort . map score . completed . nonCorrupt where completed = map (completeChunks . fst) nonCorrupt = filter notCorrupt . map resolveChunks score :: [Char] -> Int score = foldl' (\s x -> s * 5 + (charScore x)) 0 where charScore :: Char -> Int charScore ')' = 1 charScore ']' = 2 charScore '}' = 3 charScore '>' = 4 charScore _ = undefined notCorrupt :: ([Char], Bool) -> Bool notCorrupt (_, corrupt) = not corrupt middle :: [a] -> a middle [] = undefined middle l = l !! (length l `quot` 2) completeChunks :: String -> String completeChunks = map close where close :: Char -> Char close c | c == '(' = ')' | c == '[' = ']' | c == '{' = '}' | c == '<' = '>' | otherwise = undefined resolveChunks :: String -> ([Char], Bool) resolveChunks = foldl' resolve ([], False) where resolve :: ([Char], Bool) -> Char -> ([Char], Bool) resolve (stack, broken) c | broken = (stack, broken) | isOpen c = (c:stack, False) | close c == head stack = (tail stack, False) | close c /= head stack = (c:stack, True) | otherwise = undefined isOpen :: Char -> Bool isOpen c | c == '(' = True | c == '[' = True | c == '{' = True | c == '<' = True | otherwise = False close :: Char -> Char close c | c == ')' = '(' | c == ']' = '[' | c == '}' = '{' | c == '>' = '<' | otherwise = undefined -- Tests testInput = [ "[({(<(())[]>[[{[]{<()<>>", "[(()[<>])]({[<{<<[]>>(", "{([(<{}[<>[]}>{[]{[(<()>", "(((({<>}<{<{<>}{[]{[]{}", "[[<[([]))<([[{}[[()]]]", "[{[{({}]{}}([{[{{{}}([]", "{<[[]]>}<{[{[{[]{()[[[]", "[<(<(<(<{}))><([]([]()", "<{([([[(<>()){}]>(<<{{", "<{([{{}}[<[[[<>{}]]]>[]]" ] test1 = solution1 testInput -- 26397 test2 = solution2 testInput -- 288957