Skip to content

Instantly share code, notes, and snippets.

@smigniot
Created December 10, 2021 06:05
Show Gist options
  • Select an option

  • Save smigniot/3279c61d80f4ac6b270650568f591613 to your computer and use it in GitHub Desktop.

Select an option

Save smigniot/3279c61d80f4ac6b270650568f591613 to your computer and use it in GitHub Desktop.
import Data.List (sort)
import qualified Data.Map.Strict as M
main = interact (\s -> parts (analysed (nel s)))
where parts lst = part1 lst ++ "\n" ++ part2 lst ++ "\n"
nel s = filter (not . null) (lines s)
analysed lines = zip lines (map inspect lines)
data Status =
Corrupted Char Char
| Incomplete String
| OK
deriving (Eq,Show)
inspect :: String -> Status
inspect line = matchPairs line []
matchPairs [] [] = OK
matchPairs [] remaining = Incomplete remaining
matchPairs ('<':cs) stack = matchPairs cs ('<':stack)
matchPairs ('(':cs) stack = matchPairs cs ('(':stack)
matchPairs ('{':cs) stack = matchPairs cs ('{':stack)
matchPairs ('[':cs) stack = matchPairs cs ('[':stack)
matchPairs ('>':cs) ('<':rest) = matchPairs cs rest
matchPairs (')':cs) ('(':rest) = matchPairs cs rest
matchPairs ('}':cs) ('{':rest) = matchPairs cs rest
matchPairs (']':cs) ('[':rest) = matchPairs cs rest
matchPairs (illegal:cs) ('<':rest) = Corrupted '>' illegal
matchPairs (illegal:cs) ('(':rest) = Corrupted ')' illegal
matchPairs (illegal:cs) ('{':rest) = Corrupted '}' illegal
matchPairs (illegal:cs) ('[':rest) = Corrupted ']' illegal
fromJust (Just x) = x
part1 analysis = let
corrupted = filter isCorrupted analysis
isCorrupted (_,Corrupted _ _) = True
isCorrupted _ = False
score = sum $ map getScore corrupted
getScore (_,Corrupted _ actual) = fromJust $ M.lookup actual scoreTable
scoreTable = M.fromList [(')',3),(']',57),('}',1197),('>',25137)]
in "Part1 score = " ++ show score
part2 analysis = let
incomplete = filter isIncomplete analysis
isIncomplete (_,Incomplete _) = True
isIncomplete _ = False
scoreTable = M.fromList [('(',1),('[',2),('{',3),('<',4)]
getScore (_,Incomplete remaining) =
foldr (\a b -> (b*5) + scoreOf a) 0 (reverse remaining)
scoreOf a = fromJust $ M.lookup a scoreTable
scores = sort $ map getScore incomplete
n = div (length scores) 2
score = scores !! n
in "Part2 score = " ++ show score
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment