From e6a4d314d70cd751154c6371b56a5b5b5a0bfc13 Mon Sep 17 00:00:00 2001 From: Dece Date: Mon, 9 Dec 2019 23:03:48 +0100 Subject: [PATCH] Day 9 --- 2019/day9.py | 6 +++++ 2019/intcode.py | 58 +++++++++++++++++++++++-------------------------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/2019/day9.py b/2019/day9.py index 556a304..982805d 100644 --- a/2019/day9.py +++ b/2019/day9.py @@ -9,9 +9,15 @@ EX3 = "104,1125899906842624,99" def main(): with open("day9.txt", "rt") as input_file: text = input_file.readlines()[0].rstrip() + codes = Intcode.parse_input(text) + + # Part 1 Intcode(codes, print_output=True).run([1]) + # Part 2 + Intcode(codes, print_output=True).run([2]) + if __name__ == "__main__": main() diff --git a/2019/intcode.py b/2019/intcode.py index b97c133..738c9ca 100644 --- a/2019/intcode.py +++ b/2019/intcode.py @@ -25,7 +25,7 @@ class PMode(IntEnum): class Intcode(object): - def __init__(self, program, print_output=False): + def __init__(self, program, print_output=False, debug=False): self._memory = program.copy() self.ip = 0 self.rel_base = 0 @@ -35,23 +35,22 @@ class Intcode(object): self.halt = False self.outputs = [] self.print_output = print_output + self.debug = debug @staticmethod def parse_input(text): return [int(i) for i in text.rstrip().split(",")] + def log(self, message, *args): + if self.debug: + print("debug:", message, *args) + def run(self, inputs=None): self.inputs = inputs or [] 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)) - try: - handler() - except Exception as exc: - sys.exit("Exception: {}".format(exc)) + handlers.get(self.ctx_op)() return self.outputs[-1] if self.outputs else 0 def get_handlers(self): @@ -78,48 +77,45 @@ class Intcode(object): def _check_memory_limits(self, index): if index >= len(self._memory): - self._extend_memory(index + 1) - - def _extend_memory(self, new_size): - if len(self._memory) >= new_size: - return - self._memory += [0] * (new_size - len(self._memory)) + new_size = index + 1 + self._memory += [0] * (new_size - len(self._memory)) def read_code(self): - code = self.mem_get(self.ip) - self.ctx_op = code % 100 - code //= 100 + raw_code = self.mem_get(self.ip) + code = raw_code % 100 + self.ctx_op = Op(code) + + code = raw_code // 100 self.ctx_modes = [] for _ in range(0, 3): self.ctx_modes.append(PMode(code % 10)) code //= 10 + self.log("read_code", raw_code, self.ctx_op, self.ctx_modes) - def param(self, index): + def param(self, index, pointer=False): mode = self.ctx_modes[index - 1] if mode == PMode.POS: address = self.mem_get(self.ip + index) - return self.mem_get(address) + return address if pointer else self.mem_get(address) elif mode == PMode.IMM: return self.mem_get(self.ip + index) elif mode == PMode.REL: - relative_jump = self.mem_get(self.ip + index) - address = self.rel_base + relative_jump - return self.mem_get(address) - - def write_pos_ofs(self, pos_offset, value): - output_pos = self.mem_get(self.ip + pos_offset) - self.mem_set(output_pos, value) + address = self.rel_base + self.mem_get(self.ip + index) + return address if pointer else self.mem_get(address) + def write_at_param(self, param_offset, value): + self.mem_set(self.param(param_offset, pointer=True), value) + def op_add(self): - self.write_pos_ofs(3, self.param(1) + self.param(2)) + self.write_at_param(3, self.param(1) + self.param(2)) self.ip += 4 def op_mul(self): - self.write_pos_ofs(3, self.param(1) * self.param(2)) + self.write_at_param(3, self.param(1) * self.param(2)) self.ip += 4 def op_in(self): - self.write_pos_ofs(1, self.inputs.pop(0)) + self.mem_set(self.param(1, pointer=True), self.inputs.pop(0)) self.ip += 2 def op_out(self): @@ -141,11 +137,11 @@ class Intcode(object): self.ip += 3 def op_lt(self): - self.write_pos_ofs(3, int(self.param(1) < self.param(2))) + self.write_at_param(3, int(self.param(1) < self.param(2))) self.ip += 4 def op_eq(self): - self.write_pos_ofs(3, int(self.param(1) == self.param(2))) + self.write_at_param(3, int(self.param(1) == self.param(2))) self.ip += 4 def op_srb(self):