diff options
Diffstat (limited to '2017/8.hs')
-rw-r--r-- | 2017/8.hs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/2017/8.hs b/2017/8.hs new file mode 100644 index 0000000..7ac76e3 --- /dev/null +++ b/2017/8.hs @@ -0,0 +1,45 @@ +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 |