diff --git a/2019/day19.py b/2019/day19.py index a31daa2..f39d8f2 100644 --- a/2019/day19.py +++ b/2019/day19.py @@ -1,28 +1,53 @@ from grid import Grid from intcode import Intcode -from tools import parse_intcode def main(): - codes = parse_intcode("day19.txt") + codes = Intcode.parse_file("day19.txt") + mgr = DroneMgr(codes) + + # Part 1 area = Grid() for y in range(50): for x in range(50): - mgr = DroneMgr(codes) mgr.run(inputs=[x, y]) - area.setv(x, y, mgr.output) + area.setv(y, x, mgr.clear()) area.dumb_print() num_affected = sum(v for _, _, v in area.values_gen()) print("Num affected:", num_affected) + # Part 2 + d = 100 - 1 + found = None + x, y = 0, 4 # skip beam being too narrow for grid + while not found: + y += 1 + while True: + mgr.run(inputs=[x, y]) + if mgr.clear() == 0: + x += 1 + continue + mgr.run(inputs=[x + d, y - d]) + if mgr.clear() == 1: + found = (x, y - d) + break + print("Found 100x100 ship with nearest corner at", found) + print("Answer:", found[0] * 10000 + found[1]) + class DroneMgr(Intcode): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.inputs = [0, 0] + def __init__(self, program, *args, **kwargs): + super().__init__(program, *args, **kwargs) + self.program = program.copy() self.output = None + def clear(self): + output = self.output + self.reset() + self.output = None + return output + def output_data(self, data): self.output = data diff --git a/2019/intcode.py b/2019/intcode.py index 344fe1e..445d3ba 100644 --- a/2019/intcode.py +++ b/2019/intcode.py @@ -25,6 +25,7 @@ class PMode(IntEnum): class Intcode(object): def __init__(self, program, debug=False): + self._program = program.copy() self._memory = program.copy() self.ip = 0 self.rel_base = 0 @@ -33,9 +34,20 @@ class Intcode(object): self.halt = False self.debug = debug self._inputs_list = None + + def reset(self): + self._memory = self._program.copy() + self.ip = 0 + self.rel_base = 0 + self.halt = False @staticmethod - def parse_input(text): + def parse_file(filename): + with open(filename, "rt") as input_file: + return Intcode.parse_text(input_file.read().rstrip()) + + @staticmethod + def parse_text(text): return [int(i) for i in text.rstrip().split(",")] def log(self, message, *args): diff --git a/tools.py b/tools.py deleted file mode 100644 index a877584..0000000 --- a/tools.py +++ /dev/null @@ -1,6 +0,0 @@ -from intcode import Intcode - - -def parse_intcode(filename): - with open(filename, "rt") as input_file: - return Intcode.parse_input(input_file.read().rstrip())