Day 7
This commit is contained in:
parent
67629545f9
commit
b74ee2b52f
0
2019/__init__.py
Normal file
0
2019/__init__.py
Normal file
22
2019/day7.py
Normal file
22
2019/day7.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import itertools
|
||||||
|
|
||||||
|
from intcode import Intcode
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open("day7.txt", "rt") as input_file:
|
||||||
|
first_line = input_file.readlines()[0]
|
||||||
|
codes = Intcode.parse_input(first_line)
|
||||||
|
|
||||||
|
phase_settings_perm = itertools.permutations(range(5), 5)
|
||||||
|
max_output = 0
|
||||||
|
for phases in phase_settings_perm:
|
||||||
|
inout = 0
|
||||||
|
for amp_id in range(5):
|
||||||
|
inout = Intcode(codes).run([phases[amp_id], inout])
|
||||||
|
max_output = max(max_output, inout)
|
||||||
|
print("Max output:", max_output)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
123
2019/intcode.py
Normal file
123
2019/intcode.py
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
""" Intcode refactored from day 7. """
|
||||||
|
|
||||||
|
from enum import IntEnum
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class Op(IntEnum):
|
||||||
|
ADD = 1
|
||||||
|
MUL = 2
|
||||||
|
IN = 3
|
||||||
|
OUT = 4
|
||||||
|
JNZ = 5
|
||||||
|
JEZ = 6
|
||||||
|
LT = 7
|
||||||
|
EQ = 8
|
||||||
|
HALT = 99
|
||||||
|
|
||||||
|
|
||||||
|
class PMode(IntEnum):
|
||||||
|
POS = 0
|
||||||
|
IMM = 1
|
||||||
|
|
||||||
|
|
||||||
|
class Intcode(object):
|
||||||
|
|
||||||
|
def __init__(self, program, print_output=False):
|
||||||
|
self.memory = program.copy()
|
||||||
|
self.ip = 0
|
||||||
|
self.inputs = []
|
||||||
|
self.ctx_op = None
|
||||||
|
self.ctx_modes = None
|
||||||
|
self.halt = False
|
||||||
|
self.outputs = []
|
||||||
|
self.print_output = print_output
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_input(text):
|
||||||
|
return [int(i) for i in text.rstrip().split(",")]
|
||||||
|
|
||||||
|
def run(self, inputs):
|
||||||
|
self.inputs = inputs
|
||||||
|
handlers = self.get_handlers()
|
||||||
|
while not self.halt:
|
||||||
|
self.read_code()
|
||||||
|
handler = handlers.get(self.ctx_op)
|
||||||
|
if not handler:
|
||||||
|
sys.exit("Wrong opcode: {}".format(self.ctx_op))
|
||||||
|
handler()
|
||||||
|
return self.outputs[-1]
|
||||||
|
|
||||||
|
def get_handlers(self):
|
||||||
|
return {
|
||||||
|
Op.ADD: self.op_add,
|
||||||
|
Op.MUL: self.op_mul,
|
||||||
|
Op.IN: self.op_in,
|
||||||
|
Op.OUT: self.op_out,
|
||||||
|
Op.JNZ: self.op_jnz,
|
||||||
|
Op.JEZ: self.op_jez,
|
||||||
|
Op.LT: self.op_lt,
|
||||||
|
Op.EQ: self.op_eq,
|
||||||
|
Op.HALT: self.op_halt,
|
||||||
|
}
|
||||||
|
|
||||||
|
def read_code(self):
|
||||||
|
code = self.memory[self.ip]
|
||||||
|
self.ctx_op = code % 100
|
||||||
|
code //= 100
|
||||||
|
self.ctx_modes = []
|
||||||
|
for _ in range(0, 3):
|
||||||
|
self.ctx_modes.append(PMode(code % 10))
|
||||||
|
code //= 10
|
||||||
|
|
||||||
|
def param(self, index):
|
||||||
|
mode = self.ctx_modes[index - 1]
|
||||||
|
if mode == PMode.POS:
|
||||||
|
return self.memory[self.memory[self.ip + index]]
|
||||||
|
elif mode == PMode.IMM:
|
||||||
|
return self.memory[self.ip + index]
|
||||||
|
|
||||||
|
def write_at(self, pos_offset, value):
|
||||||
|
output_pos = self.memory[self.ip + pos_offset]
|
||||||
|
self.memory[output_pos] = value
|
||||||
|
|
||||||
|
def op_add(self):
|
||||||
|
self.write_at(3, self.param(1) + self.param(2))
|
||||||
|
self.ip += 4
|
||||||
|
|
||||||
|
def op_mul(self):
|
||||||
|
self.write_at(3, self.param(1) * self.param(2))
|
||||||
|
self.ip += 4
|
||||||
|
|
||||||
|
def op_in(self):
|
||||||
|
self.write_at(1, self.inputs.pop(0))
|
||||||
|
self.ip += 2
|
||||||
|
|
||||||
|
def op_out(self):
|
||||||
|
self.outputs.append(self.param(1))
|
||||||
|
if self.print_output:
|
||||||
|
print(">", self.outputs[-1])
|
||||||
|
self.ip += 2
|
||||||
|
|
||||||
|
def op_jnz(self):
|
||||||
|
if self.param(1) != 0:
|
||||||
|
self.ip = self.param(2)
|
||||||
|
else:
|
||||||
|
self.ip += 3
|
||||||
|
|
||||||
|
def op_jez(self):
|
||||||
|
if self.param(1) == 0:
|
||||||
|
self.ip = self.param(2)
|
||||||
|
else:
|
||||||
|
self.ip += 3
|
||||||
|
|
||||||
|
def op_lt(self):
|
||||||
|
self.write_at(3, int(self.param(1) < self.param(2)))
|
||||||
|
self.ip += 4
|
||||||
|
|
||||||
|
def op_eq(self):
|
||||||
|
self.write_at(3, int(self.param(1) == self.param(2)))
|
||||||
|
self.ip += 4
|
||||||
|
|
||||||
|
def op_halt(self):
|
||||||
|
self.halt = True
|
Loading…
Reference in a new issue