summaryrefslogtreecommitdiff
path: root/2017/8.hs
diff options
context:
space:
mode:
Diffstat (limited to '2017/8.hs')
-rw-r--r--2017/8.hs45
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