From 695ebdc358096146b7d2594aa252c02027c9dc3f Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 23 Dec 2017 10:55:40 +0100 Subject: Day 23 Nice one, having to actually look at the input for once. :) --- 2017/23-prog.txt | 13 +++++++++++++ 2017/23.hs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2017/23.in | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 2017/23-prog.txt create mode 100644 2017/23.hs create mode 100644 2017/23.in 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 -- cgit v1.2.3