From 525a0046b758ba54c5a6b54c14fccd24579064e1 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Sat, 23 Dec 2017 12:08:15 +0100 Subject: finished Day 23 --- Puzzle23 | Bin 0 -> 34392 bytes Puzzle23.hi | Bin 0 -> 1848 bytes Puzzle23.hs | 33 ++++++++++++++++++++++++++++++++ Puzzle23.o | Bin 0 -> 25264 bytes Puzzle23translation.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+) create mode 100755 Puzzle23 create mode 100644 Puzzle23.hi create mode 100644 Puzzle23.hs create mode 100644 Puzzle23.o create mode 100644 Puzzle23translation.md diff --git a/Puzzle23 b/Puzzle23 new file mode 100755 index 0000000..fb77037 Binary files /dev/null and b/Puzzle23 differ diff --git a/Puzzle23.hi b/Puzzle23.hi new file mode 100644 index 0000000..4ef63d0 Binary files /dev/null and b/Puzzle23.hi differ diff --git a/Puzzle23.hs b/Puzzle23.hs new file mode 100644 index 0000000..e00afb2 --- /dev/null +++ b/Puzzle23.hs @@ -0,0 +1,33 @@ +import Data.List.Split (splitOn) +import Data.Map (Map) +import qualified Data.Map as Map + +exec :: [[Char]] -> Int -> Int -> Map Char Int -> Int +exec rom n addr regs + | addr >= length rom || addr < 0 = n + | op == "set" = exec rom n (addr + 1) (Map.insert dest val regs) + | op == "sub" = exec rom n (addr + 1) (Map.insert dest (dval - val) regs) + | op == "mul" = exec rom (n + 1) (addr + 1) (Map.insert dest (dval * val) regs) + | op == "jnz" = exec rom n (if dval /= 0 then addr + val else addr + 1) regs + where ins = rom !! addr + op:[dest]:xs = splitOn " " ins + dval = getVal [dest] + val = getVal $ head xs + getVal xs = if head xs `elem` alphabet then regs Map.! (head xs) else read xs + +isPrime :: Int -> Bool +isPrime x = and $ ((/=0) . rem x) <$> [2 .. floor $ sqrt $ fromIntegral x] + +solve2 = length $ filter (==False) $ isPrime <$> [105700, 105717 .. 122700] -- The last number, 122700 should not be included because according to the assembly code when b == c the program terminates without checking primality of b. But the AOC website only accepted the answer when it is included. + +alphabet = ['a'..'h'] + +initRegs :: Map Char Int +initRegs = Map.fromList $ zip ['a'..'h'] (cycle [0]) + + +solve1 :: [Char] -> Int +solve1 xs = exec (lines xs) 0 0 initRegs + + +input = "set b 57\nset c b\njnz a 2\njnz 1 5\nmul b 100\nsub b -100000\nset c b\nsub c -17000\nset f 1\nset d 2\nset e 2\nset g d\nmul g e\nsub g b\njnz g 2\nset f 0\nsub e -1\nset g e\nsub g b\njnz g -8\nsub d -1\nset g d\nsub g b\njnz g -13\njnz f 2\nsub h -1\nset g b\nsub g c\njnz g 2\njnz 1 3\nsub b -17\njnz 1 -23" diff --git a/Puzzle23.o b/Puzzle23.o new file mode 100644 index 0000000..fd2fdef Binary files /dev/null and b/Puzzle23.o differ diff --git a/Puzzle23translation.md b/Puzzle23translation.md new file mode 100644 index 0000000..018e129 --- /dev/null +++ b/Puzzle23translation.md @@ -0,0 +1,51 @@ +Translation from the assembly code to pseudocode: + +''' +b = 105700 +c = 122700 + +for b = 105700, 105717, .., 122683 + f = 1 + for d = 2 .. b + for e = 2 .. b + if d * e == b then f = 0 + if f == 0 then h += 1 +return h +''' + +The original assembly code: + +''' +set b 57 +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