advent-2021/10/solution.hs

61 lines
1.7 KiB
Haskell

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