96 lines
2.4 KiB
Haskell
96 lines
2.4 KiB
Haskell
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
|