aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuchen Pei <me@ypei.me>2017-12-23 12:08:15 +0100
committerYuchen Pei <me@ypei.me>2017-12-23 12:08:15 +0100
commit525a0046b758ba54c5a6b54c14fccd24579064e1 (patch)
tree8efed5c0cec836b1ea4c3c6c82647c8f1bd7b9c7
parent15d597662b7cd5eb950ecf30ddb452cd1f247bf8 (diff)
finished Day 23
-rwxr-xr-xPuzzle23bin0 -> 34392 bytes
-rw-r--r--Puzzle23.hibin0 -> 1848 bytes
-rw-r--r--Puzzle23.hs33
-rw-r--r--Puzzle23.obin0 -> 25264 bytes
-rw-r--r--Puzzle23translation.md51
5 files changed, 84 insertions, 0 deletions
diff --git a/Puzzle23 b/Puzzle23
new file mode 100755
index 0000000..fb77037
--- /dev/null
+++ b/Puzzle23
Binary files differ
diff --git a/Puzzle23.hi b/Puzzle23.hi
new file mode 100644
index 0000000..4ef63d0
--- /dev/null
+++ b/Puzzle23.hi
Binary files 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
--- /dev/null
+++ b/Puzzle23.o
Binary files 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
+'''