import Control.Monad import qualified Data.Map.Strict as Map import Data.Map.Strict ((!)) import Data.Maybe data Ins = Ins String Int Cond data Cond = Cond String (Int -> Bool) type State = Map.Map String Int initState :: State initState = Map.empty condTable :: Map.Map String (Int -> Int -> Bool) condTable = Map.fromList [("<", flip (<)) ,(">", flip (>)) ,("<=", flip (<=)) ,(">=", flip (>=)) ,("==", flip (==)) ,("!=", flip (/=))] parse :: String -> Ins parse str = case words str of [name, "inc", val, "if", cname, op, cval] -> Ins name ( read val) (Cond cname ((condTable ! op) (read cval))) [name, "dec", val, "if", cname, op, cval] -> Ins name (-read val) (Cond cname ((condTable ! op) (read cval))) exec :: State -> Ins -> State exec mp (Ins name delta (Cond cname cop)) = let val = fromMaybe 0 (Map.lookup name mp) cval = fromMaybe 0 (Map.lookup cname mp) in if cop cval then Map.insert name (val + delta) mp else mp main :: IO () main = do input <- liftM (map parse . lines) (readFile "8.in") let states = scanl exec initState input print $ maximum $ Map.elems (last states) print $ maximum $ map (maximum . (0 :) . Map.elems) states