summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2017/23-prog.txt13
-rw-r--r--2017/23.hs54
-rw-r--r--2017/23.in32
3 files changed, 99 insertions, 0 deletions
diff --git a/2017/23-prog.txt b/2017/23-prog.txt
new file mode 100644
index 0000000..7fbc42a
--- /dev/null
+++ b/2017/23-prog.txt
@@ -0,0 +1,13 @@
+for (b = 106700; b != 123700; b += 17) {
+ f = 1; // is b prime?
+
+ for (d = 2; d != b; d++) {
+ for (e = 2; e != b; e++) {
+ if (d * e == b) f = 0; // nope, it's d * e
+ }
+ }
+
+ if (f == 0) h++;
+}
+
+// h = numprimes([106700, 106717 ... 123700])
diff --git a/2017/23.hs b/2017/23.hs
new file mode 100644
index 0000000..cd962f6
--- /dev/null
+++ b/2017/23.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE BangPatterns #-}
+import Control.Monad
+import Data.Char
+import qualified Data.Map.Strict as Map
+import Data.Map.Strict ((!))
+import Debug.Trace
+
+
+data Ref = Reg Int | Const Int
+ deriving Show
+
+data Ins = Set Int Ref | Sub Int Ref | Mul Int Ref | Jnz Ref Ref
+ deriving Show
+
+parse :: String -> Ins
+parse str = case words str of
+ ["set", x, y] -> Set (preg x) (pref y)
+ ["sub", x, y] -> Sub (preg x) (pref y)
+ ["mul", x, y] -> Mul (preg x) (pref y)
+ ["jnz", x, y] -> Jnz (pref x) (pref y)
+ where
+ pref s = if isAlpha (head s) then Reg (preg s) else Const (read s)
+ preg [c] = ord c - ord 'a'
+
+run :: [Ins] -> Int
+run program = go 0 0 (Map.fromList [(i, 0) | i <- [0..7]])
+ where
+ proglen :: Int
+ proglen = length program
+
+ go :: Int -> Int -> Map.Map Int Int -> Int
+ go !idx !count _ | idx < 0 || idx >= proglen = count
+ go !idx !count !regs = case program !! idx of
+ Set reg ref -> go (succ idx) count (Map.insert reg (getref ref regs) regs)
+ Sub reg ref -> go (succ idx) count (Map.insert reg (regs ! reg - getref ref regs) regs)
+ Mul reg ref -> go (succ idx) (succ count) (Map.insert reg (regs ! reg * getref ref regs) regs)
+ Jnz (Const 0) ref -> go (succ idx) count regs
+ Jnz (Const _) ref -> go (idx + getref ref regs) count regs
+ Jnz (Reg r) ref -> go (idx + if regs ! r == 0 then 1 else getref ref regs) count regs
+
+ getref :: Ref -> Map.Map Int Int -> Int
+ getref (Const i) _ = i
+ getref (Reg r) regs = regs ! r
+
+isprime :: Int -> Bool
+isprime n =
+ let s = floor (sqrt (fromIntegral n))
+ in not . null $ filter (\d -> n `rem` d == 0) [2..s]
+
+main :: IO ()
+main = do
+ program <- liftM (map parse . lines) (readFile "23.in")
+ print $ run program
+ print $ sum $ map (fromEnum . isprime) [106700, 106717 .. 123700]
diff --git a/2017/23.in b/2017/23.in
new file mode 100644
index 0000000..8155688
--- /dev/null
+++ b/2017/23.in
@@ -0,0 +1,32 @@
+set b 67
+set c b
+jnz a 2
+jnz 1 5
+mul b 100
+sub b -100000
+set c b
+sub c -17000
+set f 1
+set d 2
+set e 2
+set g d
+mul g e
+sub g b
+jnz g 2
+set f 0
+sub e -1
+set g e
+sub g b
+jnz g -8
+sub d -1
+set g d
+sub g b
+jnz g -13
+jnz f 2
+sub h -1
+set g b
+sub g c
+jnz g 2
+jnz 1 3
+sub b -17
+jnz 1 -23