import Data.List main :: IO () main = do input <- readFile "10/input.txt" let x = lines input -- Problem 1 print $ f x -- Problem 2 print $ g x where f = solve 1 g = solve 2 -- | A syntax error type. data Error = Incomplete Char | Corrupted Char deriving Show -- | Check if the error is that the found character doesn't match the -- | expected character. corrupted :: Error -> Bool corrupted (Corrupted _) = True corrupted _ = False -- | Check if the error is that the line is incomplete. incomplete :: Error -> Bool incomplete = not . corrupted solve :: Int -> [String] -> Int solve 1 = sum . (>>= (map score . take 1 . filter corrupted . synck [])) solve 2 = mid . sort . map calc . filter (all incomplete) . map (synck []) where calc = foldl (\a e -> (a * 5) + score e) 0 mid ls = ls !! (length ls `div` 2) -- | Run the syntax checker on the given line. synck :: [Char] -- ^ A stack of expected characters -> String -- ^ The remaining characters to check -> [Error] -- ^ A list of syntax errors found for the given line synck ex [] = map Incomplete ex synck ex (x : xs) | x == '<' = synck ('>' : ex) xs | x == '{' = synck ('}' : ex) xs | x == '(' = synck (')' : ex) xs | x == '[' = synck (']' : ex) xs | head ex == x = synck (tail ex) xs | otherwise = Corrupted x : synck ex xs -- | Score the severity of the error. score :: Error -> Int score (Corrupted ')') = 3 score (Corrupted ']') = 57 score (Corrupted '}') = 1197 score (Corrupted '>') = 25137 score (Incomplete ')') = 1 score (Incomplete ']') = 2 score (Incomplete '}') = 3 score (Incomplete '>') = 4