class SpringDroid: def __init__(self) -> None: t = open('../resources/input_21.txt') lines = t.readlines() t.close() program = list(map(lambda x: int(x), lines[0].split(sep=','))) self.computer = IntcodeComputer(program) def run_spring_script(self, spring_script: [str]): mem, out, exit_code = self.computer.run_program() print(SpringDroid.decode(out)) for line in spring_script: int_code = SpringDroid.encode(line) mem, out, exit_code = self.computer.run_program(input=int_code, reset_memory=False, reset_pointer=False, reset_relative_pointer=False) if exit_code == 1: print(SpringDroid.decode(out)) else: print('{}{}'.format(SpringDroid.decode(out[:-1]), out[-1])) @staticmethod def decode(code: str): return reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), code)) @staticmethod def encode(code: str): return list(map(lambda x: ord(x), code))
def test_result_for_part_two_day_five(self): t = open('../resources/input_5.txt') lines = t.readlines() t.close() original_inputs = list(map(lambda x: int(x), lines[0].split(sep=','))) computer = IntcodeComputer(original_inputs) computer.run_program(input=[5])
def __init__(self) -> None: t = open('resources/input_25.txt') lines = t.readlines() t.close() program = list(map(lambda x: int(x), lines[0].split(sep=','))) self.computer = IntcodeComputer(program)
def __init__(self, ) -> None: t = open('../resources/input_17.txt') lines = t.readlines() t.close() program = list(map(lambda x: int(x), lines[0].split(sep=','))) self.computer = IntcodeComputer(program) self.image = '' self.intersections = list()
def test_opcode_3(self): inputs = [3, 2, 0] expected_memory = [3, 2, 99] computer = IntcodeComputer(inputs) outputs = computer.run_program(input=[99])[0] assert_equal(outputs, expected_memory)
def test_result_for_first_part(self): t = open('../resources/input_2.txt') lines = t.readlines() t.close() inputs = list(map(lambda x: int(x), lines[0].split(sep=','))) computer = IntcodeComputer(inputs) result = computer.run_program(parameters=[12, 2])[0] print('The value is: ' + str(result[0]))
def test_result_part_two_day_nine(self): t = open('../resources/input_9.txt') lines = t.readlines() t.close() original_inputs = list(map(lambda x: int(x), lines[0].split(sep=','))) computer = IntcodeComputer(original_inputs) output = computer.run_program(input=[2])[1] print('Resulting coordinates of the distress signal: {}'.format(output))
def test_result_part_one_day_nine(self): t = open('../resources/input_9.txt') lines = t.readlines() t.close() original_inputs = list(map(lambda x: int(x), lines[0].split(sep=','))) computer = IntcodeComputer(original_inputs) output = computer.run_program(input=[1])[1] print('Result: {}'.format(output)) assert_equal(output, [3409270027])
def test_compare(self): ### manual testing of various programs, check printed output to verify inputs = [ 3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31, 1106, 0, 36, 98, 0, 0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104, 999, 1105, 1, 46, 1101, 1000, 1, 20, 4, 20, 1105, 1, 46, 98, 99 ] computer = IntcodeComputer(inputs) computer.run_program(input=[100])
def test_run_program(self): inputs = [ ([1, 0, 0, 0, 99], [2, 0, 0, 0, 99]), ([2, 3, 0, 3, 99], [2, 3, 0, 6, 99]), ([2, 4, 4, 5, 99, 0], [2, 4, 4, 5, 99, 9801]), ([1, 1, 1, 4, 99, 5, 6, 0, 99], [30, 1, 1, 4, 2, 5, 6, 0, 99]) ] for input_tuple in inputs: computer = IntcodeComputer(input_tuple[0]) result = computer.run_program()[0] assert_equal(result, input_tuple[1])
class SantaRescue: def __init__(self) -> None: t = open('resources/input_25.txt') lines = t.readlines() t.close() program = list(map(lambda x: int(x), lines[0].split(sep=','))) self.computer = IntcodeComputer(program) def run(self, command: str): encoded = SantaRescue.encode(command) mem, out, exit_code = self.computer.run_program(input=encoded, reset_memory=False, reset_pointer=False, reset_relative_pointer=False) decoded = SantaRescue.decode(out) print(decoded) @staticmethod def decode(code: str): return reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), code)) @staticmethod def encode(code: str): return list(map(lambda x: ord(x), code))
def test_result_for_second_part(self): expected_value = 19690720 t = open('../resources/input_2.txt') lines = t.readlines() t.close() original_inputs = list(map(lambda x: int(x), lines[0].split(sep=','))) result = 0 computer = IntcodeComputer(original_inputs) for i in range(100): for j in range(100): result = computer.run_program(parameters=[i, j])[0] if result[0] == expected_value: print('noun: ' + str(i) + ' verb: ' + str(j)) print('result is: ' + str(100 * i + j)) break if result[0] == expected_value: break
def __init__(self) -> None: t = open('../resources/input_23.txt') lines = t.readlines() t.close() program = list(map(lambda x: int(x), lines[0].split(sep=','))) self.computers = [IntcodeComputer(program) for i in range(50)] self.packet_queues = [list() for i in range(50)] for c in range(50): mem, out, exit_code = self.computers[c].run_program(input=[c]) print('Booting computer {}: {}'.format(c, out)) self.nat_storage = None self.nat_sent_y = list()
class RepairDroid: def __init__(self, program: [int]) -> None: self.computer = IntcodeComputer(program) self.map = dict() def find(self): seen = dict() pos = np.array((0, 0)) all_seen = False while not all_seen: has_to_backtrack = True for i in [1, 4, 2, 3]: if tuple(pos + RepairDroid.direction(i)) not in seen: has_to_backtrack = False mem, out, exit_code = self.computer.run_program( input=[i], reset_relative_pointer=False, reset_pointer=False, reset_memory=False) assert len(out) == 1 out_code = out[0] if out_code == 0: seen[tuple(pos + RepairDroid.direction(i))] = '#' elif out_code == 1: pos += RepairDroid.direction(i) seen[tuple(pos)] = '.' elif out_code == 2: pos += RepairDroid.direction(i) seen[tuple(pos)] = '+' break if has_to_backtrack: path = list() path.append(tuple(pos)) commands = RepairDroid.backtrack(seen, path, list()) for i in commands[0]: mem, out, exit_code = self.computer.run_program( input=[i], reset_relative_pointer=False, reset_pointer=False, reset_memory=False) if out[0] != 0: pos += RepairDroid.direction(i) else: print('Backtracking failed!') all_seen = has_to_backtrack and not commands[0] RepairDroid.print_screen(seen, tuple(pos)) self.map = seen tree = RepairDroid.BFS(seen) path_to_oxygen = list() while tree.parent: path_to_oxygen.append(tree.data[0]) tree = tree.parent target_pos = None shortest_path_map = seen.copy() for pos in path_to_oxygen: if pos != (0, 0) and shortest_path_map[pos] != '+': shortest_path_map[pos] = 'X' elif shortest_path_map[pos] == '+': target_pos = pos RepairDroid.print_screen(shortest_path_map, tuple(pos)) print('Target: {}'.format(target_pos)) return path_to_oxygen, target_pos @staticmethod def BFS(map: dict): tree = Node(((0, 0), 'O')) discovered = list() q = list() discovered.append(tree.data[0]) q.append(tree) while q: v = q.pop() if v.data[1] == '+': return v children = list() for i in range(1, 5): pos_to_check = tuple( np.array(v.data[0]) + RepairDroid.direction(i)) if pos_to_check in map and pos_to_check not in discovered: if map[pos_to_check] != '#': children.append(pos_to_check) for c in children: if c not in discovered: discovered.append(c) node = Node((c, map[c])) v.add_node(v, node) q.append(node) def oxygenate(self, oxygen_pos: tuple): pos_map = self.map.copy() pos_map[oxygen_pos] = 'O' minutes = 0 #self.print_screen(pos_map, (0, 0)) while '.' in pos_map.values(): #self.print_screen(pos_map, (0, 0)) minutes += 1 pos_to_oxygenate = list() for pos in pos_map.keys(): if pos_map[pos] == 'O': pos_to_oxygenate.append(pos) for pos in pos_to_oxygenate: if pos_map[pos] == 'O': for i in range(1, 5): pos_to_check = tuple( np.array(pos) + RepairDroid.direction(i)) if pos_to_check in pos_map and pos_map[ pos_to_check] == '.': pos_map[pos_to_check] = 'O' return minutes @staticmethod def backtrack(seen: dict, path: list, path_commands: list): found = False for i in [1, 4, 2, 3]: if not found: field = np.array(path[-1:][0]) + RepairDroid.direction(i) if tuple(field) in seen: if seen[tuple(field)] != '#' and tuple(field) not in path: path.append(tuple(field)) path_commands.append(i) path_commands, found = RepairDroid.backtrack( seen, path, path_commands) else: return path_commands, True if not found and path_commands: path_commands.pop() path.pop() return path_commands, found @staticmethod def direction(dir: int): if dir == 1: return np.array((0, -1)) elif dir == 2: return np.array((0, 1)) elif dir == 3: return np.array((-1, 0)) elif dir == 4: return np.array((1, 0)) @staticmethod def get_reverse_direction(dir: int): if dir == 1: return 2 elif dir == 2: return 1 elif dir == 3: return 4 elif dir == 4: return 3 @staticmethod def print_screen(seen: dict, pos: tuple): if seen and pos: x_max = max(map(lambda t: t[0], seen.keys())) x_min = min(map(lambda t: t[0], seen.keys())) y_max = max(map(lambda t: t[1], seen.keys())) y_min = min(map(lambda t: t[1], seen.keys())) for y in range(y_min, y_max + 1): line = '' for x in range(x_min, x_max + 1): if (x, y) == (0, 0): line += 'O' else: if (x, y) != pos: if (x, y) in seen: line += seen[(x, y)] else: line += ' ' else: line += 'x' print(line) print('----------------------------------')
def test_opcode_9_and_relative(self): program = [109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99] computer = IntcodeComputer(program) print(computer.run_program()[1])
class TractorBeam: def __init__(self) -> None: t = open('../resources/input_19.txt') lines = t.readlines() t.close() program = list(map(lambda x: int(x), lines[0].split(sep=','))) self.computer = IntcodeComputer(program) def get_affected_fields(self, max_x: int, max_y: int): affected = 0 for x in range(max_x): for y in range(max_y): mem, out, exit_code = self.computer.run_program(input=[x, y]) if out: if out[0] == 1: affected += 1 print('{}, {} -> {}'.format(x, y, out)) return affected def fit_ship(self): x = 0 y = 0 affected_area = set() left_edge = 0 for y in range(1000): found_in_line = False for x in range(left_edge, 1000): mem, out, exit_code = self.computer.run_program(input=[x, y]) if out: if out[0] == 1: if not found_in_line: found_in_line = True left_edge = x affected_area.add((x, y)) elif out[0] == 0: if found_in_line: break if len(affected_area) >= 100 * 100: for pos in affected_area: xx = pos[0] yy = pos[1] if (xx + 99, yy) in affected_area and ( xx, yy + 99) in affected_area and ( xx + 99, yy + 99) in affected_area: return (xx, yy) def fit_better(self): left_edge = 0 y = 0 affected_area = list() while True: found_in_line = False for x in range(left_edge, left_edge + 100): mem, out, exit_code = self.computer.run_program(input=[x, y]) if out[0] == 1: if not found_in_line: found_in_line = True left_edge = x for xx in range(left_edge, left_edge + 100): mem, out, exit_code = self.computer.run_program( input=[xx, y]) if out[0] == 1: affected_area.append((xx, y)) if (xx - 100, y - 100) in affected_area: if (xx - 100, y) in affected_area and ( xx, y - 100) in affected_area: return (xx - 100, y - 100) elif out[0] == 0: if found_in_line: #TractorBeam.print_beam(x, xx, True) break break #if not found_in_line: # TractorBeam.print_beam(left_edge, left_edge + 100, False) y += 1 def fit_even_better(self): s_length = 99 x = 0 y = 100 while True: while True: mem, out, exit_code = self.computer.run_program(input=[x, y]) if out[0] == 1: if self.computer.run_program( input=[x + s_length, y - s_length])[1][0] == 1: return x * 10000 + y - 99 else: break else: x += 1 y += 1 #13690873 wrong @staticmethod def print_beam(le, re, found): s = reduce(lambda l, r: l + r, ['.' for x in range(le)], '.') if found: s += reduce(lambda l, r: l + r, ['#' for x in range(le, re)], '.') else: s += reduce(lambda l, r: l + r, ['.' for x in range(le, re)], '.') print(s)
def __init__(self, game: [int]) -> None: self.computer = IntcodeComputer(game) self.parameters = [2] self.screen = [[' ' for x in range(24)] for y in range(42)]
class Arcade: def __init__(self, game: [int]) -> None: self.computer = IntcodeComputer(game) self.parameters = [2] self.screen = [[' ' for x in range(24)] for y in range(42)] def run(self, input: int = None): if self.parameters: param = list() param.append(self.parameters.pop()) else: param = None if input is not None: inp = [input] else: inp = None hi_score = 0 exit_code = 1 while exit_code != 0: mem, out, exit_code = self.computer.run_program( parameters=[2], input=inp, reset_memory=False, reset_pointer=False, reset_relative_pointer=False) p = 0 ball_x, bally = 0, 0 pad_x, pad_y = 0, 0 while p + 3 <= len(out): c = '~' if out[p + 2] == 0: c = ' ' elif out[p + 2] == 1: c = '#' elif out[p + 2] == 2: c = 'X' elif out[p + 2] == 3: c = '-' pad_x = out[p] pad_y = out[p + 1] elif out[p + 2] == 4: c = 'O' ball_x = out[p] ball_y = out[p + 1] else: c = out[p + 2] x = out[p] y = out[p + 1] if x == -1 and y == 0: hi_score = out[p + 2] else: self.screen[x][y] = c p += 3 if ball_x > pad_x: inp = [1] elif ball_x < pad_x: inp = [-1] else: inp = [0] print('Highscore: {}'.format(hi_score)) self.print_screen(self.screen) def print_screen(self, screen): for y in range(len(screen[0])): line = '' for x in range(len(screen)): line += screen[x][y] print(line)
def test_opcode_9_and_relative_2(self): program = [1102, 34915192, 34915192, 7, 4, 7, 99, 0] computer = IntcodeComputer(program) print(computer.run_program()[1])
def test_opcode_9_and_relative_3(self): program = [104, 1125899906842624, 99] computer = IntcodeComputer(program) print(computer.run_program()[1])
def __init__(self, program: [int]) -> None: self.computer = IntcodeComputer(program) self.map = dict()
def test_opcode_4(self): inputs = [4, 2, 99] computer = IntcodeComputer(inputs) computer.run_program()
class CameraSystem: def __init__(self, ) -> None: t = open('../resources/input_17.txt') lines = t.readlines() t.close() program = list(map(lambda x: int(x), lines[0].split(sep=','))) self.computer = IntcodeComputer(program) self.image = '' self.intersections = list() def show_image(self): mem, out, exit_code = self.computer.run_program(reset_memory=False, reset_pointer=False, reset_relative_pointer=False) s = reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out)) self.image = s print(s) def find_intersections(self): img = self.image length = self.image.index('\n') + 1 height = int(len(self.image) / length) intersections = list() for y in range(height): for x in range(length): if 0 < y < height - 1 and 0 < x < length - 1: if (img[x - 1 + y * length] == '#' and img[x + y * length] == '#' and img[x + 1 + y * length] == '#' and img[x + (y - 1) * length] == '#' and img[x + (y + 1) * length] == '#'): img = img[:x + y * length] + 'O' + img[x + 1 + y * length:] intersections.append((x, y)) print(img) self.intersections = intersections print('Sum of alignment params: {}'.format(np.array(list(map(lambda t: t[0] * t[1], intersections))).sum())) def rescue(self): self.computer.run_program(parameters=[2]) main = 'B,B,A,C,B,C,A,C,B,A\n' A = 'L,6,L,4,R,8,R,8\n' B = 'L,4,L,10,L,6\n' C = 'L,6,R,8,L,10,L,8,L,8\n' main = self.to_input(main) a = self.to_input(A) b = self.to_input(B) c = self.to_input(C) mem, out, exit_code = self.computer.run_program(input=main, reset_memory=False, reset_pointer=False, reset_relative_pointer=False) print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out))) mem, out, exit_code = self.computer.run_program(input=a, reset_memory=False, reset_pointer=False, reset_relative_pointer=False) print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out))) mem, out, exit_code = self.computer.run_program(input=b, reset_memory=False, reset_pointer=False, reset_relative_pointer=False) print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out))) mem, out, exit_code = self.computer.run_program(input=c, reset_memory=False, reset_pointer=False, reset_relative_pointer=False) print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out))) mem, out, exit_code = self.computer.run_program(input=self.to_input('n\n'), reset_memory=False, reset_pointer=False, reset_relative_pointer=False) print(reduce(lambda x, y: x + y, map(lambda x: str(chr(x)), out[:-1]))) print('Total space dust collected: {}'.format(out[-1])) def to_input(self, s): return list(map(lambda c: ord(c), s)) @staticmethod def encode_LZW(s: str) -> [str]: codes = list() idx, off = 0, 1 scanned = False while not scanned: sub = s[idx:idx + off] if sub not in codes: codes.append(sub) idx += off off = 1 else: off += 1 if idx + off > len(s): scanned = True codes.append(sub) return codes