This commit is contained in:
Jonathan Chan 2018-12-19 00:02:06 -08:00
parent 1bb2027bd0
commit 04c021ff22
6 changed files with 142 additions and 5 deletions

View File

@ -30,7 +30,7 @@ Now located in this repository's wiki.
| 16 | ~ 1 |
| 17 | ~ 15 |
| 18 | ~ 6 |
| 19 | |
| 19 | ~ 3 |
| 20 | |
| 21 | |
| 22 | |

View File

@ -30,4 +30,4 @@ import qualified Day24
import qualified Day25
main :: IO ()
main = Day18.main
main = Day19.main

37
input/19.txt Normal file
View File

@ -0,0 +1,37 @@
#ip 4
addi 4 16 4
seti 1 1 1
seti 1 7 3
mulr 1 3 2
eqrr 2 5 2
addr 2 4 4
addi 4 1 4
addr 1 0 0
addi 3 1 3
gtrr 3 5 2
addr 4 2 4
seti 2 3 4
addi 1 1 1
gtrr 1 5 2
addr 2 4 4
seti 1 6 4
mulr 4 4 4
addi 5 2 5
mulr 5 5 5
mulr 4 5 5
muli 5 11 5
addi 2 1 2
mulr 2 4 2
addi 2 6 2
addr 5 2 5
addr 4 0 4
seti 0 0 4
setr 4 5 2
mulr 2 4 2
addr 4 2 2
mulr 4 2 2
muli 2 14 2
mulr 2 4 2
addr 5 2 5
seti 0 5 0
seti 0 2 4

41
input/19_notes.txt Normal file
View File

@ -0,0 +1,41 @@
#ip 4
0 1 2 3 4 5 6
a b c d ip f g = 0
int a = 0;
0 addi 4 16 4 ip += 16 goto L1 int f = 10551264;
1 seti 1 1 1 b = 1 L8: b = 1 for (int b = 1; b <= f; b++) {
2 seti 1 7 3 d = 1 L7: d = 1 for (int d = 1; d <= f; d++) {
3 mulr 1 3 2 c = b * d L5: c = b * d
4 eqrr 2 5 2 c = c == f if (b * d == f) if (b * d == f)
5 addr 2 4 4 ip = ip + c then goto L2
6 addi 4 1 4 ip += 1 else goto L3
7 addr 1 0 0 a += b L2: a += b a += b;
8 addi 3 1 3 d += 1 L3: d++
9 gtrr 3 5 2 c = d > f if (d > f)
10 addr 4 2 4 ip += c then goto L4
11 seti 2 3 4 ip = 2 else goto L5 }
12 addi 1 1 1 b += 1 L4: b++
13 gtrr 1 5 2 c = b > f if (b > f)
14 addr 2 4 4 ip += c then goto L6
15 seti 1 6 4 ip = 1 else goto L7 }
16 mulr 4 4 4 ip *= ip L6: return return a;
17 addi 5 2 5 f += 2 L1: f = 2
18 mulr 5 5 5 f *= f f = 2^2
19 mulr 4 5 5 f *= ip f = 2^2 * 19
20 muli 5 11 5 f *= 11 f = 2^2 * 19 * 11 = 836
21 addi 2 1 2 c += 1 c = 1
22 mulr 2 4 2 c *= ip c = 1 * 22
23 addi 2 6 2 c += 6 c = 1 * 22 + 6
24 addr 5 2 5 f += c f = 836 + 1 * 22 + 6 = 864
25 addr 4 0 4 ip += a if (a == 1) then goto L9
26 seti 0 0 4 ip = 0 else goto L8
27 setr 4 5 2 c = ip L9: c = 27
28 mulr 2 4 2 c *= ip c = 27*28
29 addr 4 2 2 c += ip c = 27*28 + 29
30 mulr 4 2 2 c *= ip c = (27*28 + 29) * 30
31 muli 2 14 2 c *= 14 c = (27*28 + 29) * 30 * 14
32 mulr 2 4 2 c *= ip c = (27*28 + 29) * 30 * 14 * 32
33 addr 5 2 5 f += c f = 864 + 10550400 = 10551264
34 seti 0 5 0 a = 0 a = 0
35 seti 0 2 4 ip = 0 goto L8

View File

@ -1,6 +1,6 @@
{-# LANGUAGE TupleSections #-}
module Day17 (main) where
module Day17_UArray (main) where
import Prelude hiding (lookup)
import Data.Foldable (maximumBy, minimumBy)

View File

@ -1,6 +1,65 @@
module Day19 (main) where
import Prelude hiding (length)
import Data.List (elemIndex)
import Data.Maybe (catMaybes)
import Data.Bits ((.|.), (.&.))
import Data.Sequence (Seq, fromList, update, adjust', index, length)
data Op = Op OpType Int Int Int
data OpType =
Addr | Addi | Mulr | Muli | Banr | Bani | Borr | Bori |
Setr | Seti | Gtir | Gtri | Gtrr | Eqir | Eqri | Eqrr
deriving Enum
type Ops = Seq Op
type Registers = Seq Int
infixl 9 !
(!) = index
execOp :: Op -> Registers -> Registers
execOp (Op Addr rA rB rC) rs = update rC (rs ! rA + rs ! rB) rs
execOp (Op Mulr rA rB rC) rs = update rC (rs ! rA * rs ! rB) rs
execOp (Op Banr rA rB rC) rs = update rC (rs ! rA .&. rs ! rB) rs
execOp (Op Borr rA rB rC) rs = update rC (rs ! rA .|. rs ! rB) rs
execOp (Op Addi rA vB rC) rs = update rC (rs ! rA + vB) rs
execOp (Op Muli rA vB rC) rs = update rC (rs ! rA * vB) rs
execOp (Op Bani rA vB rC) rs = update rC (rs ! rA .&. vB) rs
execOp (Op Bori rA vB rC) rs = update rC (rs ! rA .|. vB) rs
execOp (Op Setr rA _ rC) rs = update rC (rs ! rA) rs
execOp (Op Seti vA _ rC) rs = update rC vA rs
execOp (Op Gtir vA rB rC) rs = update rC (fromEnum $ vA > rs ! rB) rs
execOp (Op Eqir vA rB rC) rs = update rC (fromEnum $ vA == rs ! rB) rs
execOp (Op Gtri rA vB rC) rs = update rC (fromEnum $ rs ! rA > vB) rs
execOp (Op Eqri rA vB rC) rs = update rC (fromEnum $ rs ! rA == vB) rs
execOp (Op Gtrr rA rB rC) rs = update rC (fromEnum $ rs ! rA > rs ! rB) rs
execOp (Op Eqrr rA rB rC) rs = update rC (fromEnum $ rs ! rA == rs ! rB) rs
opNames = ["addr","addi","mulr","muli","banr","bani","borr","bori","setr","seti","gtir","gtri","gtrr","eqir","eqri","eqrr"]
parse :: String -> (Int, Ops)
parse input =
let ipBinding:rest = lines input
ip = read $ drop 4 ipBinding
ops = fromList $ map parseOp rest
in (ip, ops)
where
parseOp str =
let opName:a:b:c:[] = words str
Just opType = toEnum <$> elemIndex opName opNames
in Op opType (read a) (read b) (read c)
-- exec :: the register to which the instruction pointer is bound -> instructions -> initial registers -> final registers
exec :: Int -> Ops -> Registers -> Registers
exec ip ops regs =
let i = regs ! ip
nextRegs = adjust' (+1) ip $ execOp (ops ! i) regs
in if i >= length ops then regs else exec ip ops nextRegs
part1 :: Int -> Ops -> Int
part1 ip ops = exec ip ops (fromList [0, 0, 0, 0, 0, 0]) ! 0
main :: IO ()
main = do
input <- readFile "input/19.txt"
print input
(ip, ops) <- parse <$> readFile "input/19.txt"
print $ part1 ip ops