def part1(data): def inf(): return 0 scanner = IntcodeComputer(data, inf) scanner.run_program() scaffold = [[]] for output in scanner.outputs: if output != 10: scaffold[-1].append(output) else: scaffold.append([]) scaffold = scaffold[:-2] total = 0 for y in range(len(scaffold) - 1): for x in range(len(scaffold[0]) - 1): if x == 0 or y == 0: continue if scaffold[y][x] in (35, 94): intersection = True for pair in ((1, 0), (0, 1), (-1, 0), (0, -1)): if scaffold[y + pair[1]][x + pair[0]] == 46: intersection = False if intersection: total += x * y return total
def part1(data): amp_program = data inputs = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] input_pointer = 0 def input_function(): nonlocal input_pointer output = inputs[input_pointer] input_pointer += 1 return output phase_settings = permutations([0, 1, 2, 3, 4]) outputs = [] for phase_setting in phase_settings: input_pointer = 0 inputs = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] for j in range(5): inputs[2 * j] = phase_setting[j] for amp in range(5): computer = IntcodeComputer(deepcopy(amp_program), input_function) computer.run_program() if amp == 4: outputs.append(computer.outputs[0]) break inputs[2 * amp + 3] = computer.outputs[0] return max(outputs)
def part1(data): def input_function(): return 1 computer = IntcodeComputer(data, input_function) computer.run_program() return computer.outputs[-1]
class EHPR(): def __init__(self, program): self.painted = defaultdict(int) self.position = Position(0,0) self.direction = Direction.Up self.computer = IntcodeComputer(program, [], "Emergency Hull Painting Robot", 0) def set_start_color(self, color): self.painted[self.position] = color def move(self, command): new_direction = (Direction(((self.direction.value + 1) % 4)) if command else Direction(((self.direction.value - 1) % 4))) new_position = Position(*(sum(x) for x in zip(self.position, movement[new_direction]))) self.direction = new_direction self.position = new_position def paint_square(self, color): self.painted[self.position] = color def execute_step(self): self.computer.add_input(self.painted[self.position]) self.computer.run_program() output = self.computer.get_output() color, command = output[-2:] self.paint_square(color) self.move(command)
def part1_and_2(data): outputs = [] for i in (1, 2): def inf(): return i computer = IntcodeComputer(data, inf) computer.run_program() outputs.append(computer.outputs[0]) return outputs
def part2(data): data[0] = 2 pointer = 0 def inf(): nonlocal pointer pointer += 1 return COMMANDS[pointer - 1] robot = IntcodeComputer(data, inf) robot.run_program() return robot.outputs[-1]
class FlyingDrone(): def __init__(self, program): self.current_position = Position(0, 0) self.computer = IntcodeComputer(program, list(Position(0, 0)), "SpaceDroneNavigation") def navigate_to_pos(self, position): self.computer.add_prog_input(list(position)) self.computer.run_program() output = self.computer.get_output() self.current_position = position return output[0]
class SpaceRoomba(): def __init__(self, program, input_inst=[], verbose=0): self.computer = IntcodeComputer( program, input_inst, "Aft Scaffolding Control and Information Interface", verbose) self.position = Position(0, 0) self.map = dict() def get_image_from_camera(self): image_output = self.computer.run_program() self.image_output = image_output return image_output def produce_scaffolding_map(self): s_map = dict() x, y = 0, 0 for num in self.image_output: if num == 35: pos = Position(x, y) s_map[pos] = '#' x += 1 elif num == 10: x = 0 y += 1 else: x += 1 return s_map
class PaintingRobot: def __init__(self, program: [int], input: [int] = []): self.computer = IntcodeComputer(program, input) self.reset() def reset(self): self.direction = Direction.NORTH self.location = 0, 0 self.seen_locations = set() self.painted_state = defaultdict(int) self.computer.reset() def run(self, program_input: [int] = []): self.computer.input = program_input while True: if self.computer.run_program(interrupting=True): break self.painted_state[self.location] = self.computer.output.pop() if self.computer.run_program(interrupting=True): break self.rotate_and_move(Rotation(self.computer.output.pop())) self.computer.input = [self.painted_state[self.location]] def rotate_and_move(self, rotate: Rotation): self.seen_locations.add(self.location) if rotate == Rotation.LEFT: self.direction -= 1 elif rotate == Rotation.RIGHT: self.direction += 1 else: raise Exception("Unexpected rotation: {rotate}") self.direction %= 4 if self.direction == Direction.NORTH: self.location = self.location[0], self.location[1] + 1 elif self.direction == Direction.EAST: self.location = self.location[0] + 1, self.location[1] elif self.direction == Direction.SOUTH: self.location = self.location[0], self.location[1] - 1 elif self.direction == Direction.WEST: self.location = self.location[0] - 1, self.location[1] else: raise Exception(f"Unexpected direction: {self.direction}")
def part_1_and_2(data): outputs = [] scripts = [ "NOT A T \n NOT T T \n AND B T \n AND C T \n NOT T T \n AND D T \n NOT T J \n NOT J J \n WALK \n", "NOT C J \n AND H J \n NOT B T \n OR T J \n NOT A T \n OR T J \n AND D J \n RUN \n" ] for i in range(2): pointer = 0 def inf(): nonlocal scripts, pointer pointer += 1 return ord(scripts[i][pointer - 1]) computer = IntcodeComputer(data, inf) computer.run_program() outputs.append(computer.outputs[-1]) return outputs
def part1(data): def inf(): return 0 computer = IntcodeComputer(data, inf) computer.run_program() programOutput = computer.outputs i = 0 blocks = set() while i < len(programOutput): if programOutput[i + 2] == 2: blocks.add((programOutput[i], programOutput[i + 1])) if programOutput[i + 2] != 2: try: blocks.remove((programOutput[i], programOutput[i + 1])) except KeyError: pass i += 3 return len(blocks)
def test_produce_copy_of_self(): test_data = "109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99" input = parse_input_data(test_data) ic = IntcodeComputer(input, [], logging=LOGGING_ON) ic.run_program() assert ic.output == input
def test_middle_number_output(): test_data = "104,1125899906842624,99" input = parse_input_data(test_data) ic = IntcodeComputer(input, [], logging=LOGGING_ON) ic.run_program() assert ic.output[0] == 1125899906842624
def test_16_digit_output(): test_data = "1102,34915192,34915192,7,4,7,99,0" input = parse_input_data(test_data) ic = IntcodeComputer(input, [], logging=LOGGING_ON) ic.run_program() assert ic.output[0] == 1219070632396864
class ArcadeCabinet(): def __init__(self, program, free_play=False, auto=False, display=True): if free_play: program = program[:] program[0] = 2 self.computer = IntcodeComputer(program, [], "Arcade Cabinet") self.gamestate = dict() self.ball, self.tile = None, None self.auto = auto self.display = display def draw_screen(self): max_x = max(x for x, y in self.gamestate.keys()) max_y = max(y for x, y in self.gamestate.keys()) score = self.gamestate[(-1, 0)] if (-1, 0) in self.gamestate else 0 printstr = "\tSCORE:\t %i\n" % score for y in range(max_y + 1): for x in range(max_x + 1): printstr = printstr + "%s" % tiles[self.gamestate[(x, y)]] printstr = printstr + "\n" sys.stdout.write(printstr) def parse_instruction(self, instruction): x, y, tile = instruction self.gamestate[(x, y)] = tile if tile == 4: self.ball = x elif tile == 3: self.tile = x def joystick(self, key='n'): if keyboard.is_pressed('a') or key == 'a': self.computer.add_input(-1) elif keyboard.is_pressed('d') or key == 'd': self.computer.add_input(1) elif keyboard.is_pressed('s') or key == 's': self.computer.add_input(0) def self_play(self): if self.tile > self.ball: return 'a' elif self.tile < self.ball: return 'd' else: return 's' def score_counter(self): score = self.gamestate[(-1, 0)] if (-1, 0) in self.gamestate else 0 sys.stdout.write("\r") sys.stdout.flush() sys.stdout.write("Score: %i" % score) def run_game(self): while not self.computer.has_stopped(): output = self.computer.run_program() for instruction in chunks(output, 3): self.parse_instruction(instruction) if self.display: self.draw_screen() time.sleep(0.07) else: self.score_counter() self.computer.input_l.clear() key = self.self_play() if self.auto else None self.joystick(key) sys.stdout.write('\n') self.draw_screen()
class RepairDroid(): def __init__(self, program, visualize=0): self.computer = IntcodeComputer(program, [], "Arcade Cabinet") self.areamap = dict() self.visualize = visualize self.startpos = Position(0,0) self.areamap[self.startpos] = Field(self.startpos, 1, -1) self.currentpos = self.startpos def move_droid(self, direction): move = movement[direction] new_pos = Position(self.currentpos.x + move[0], self.currentpos.y + move[1]) self.computer.add_input(direction.value) output = self.computer.run_program() if new_pos not in self.areamap: new_field = Field(new_pos, output[-1], self.areamap[self.currentpos].dist) self.areamap[new_pos] = new_field if new_field.type == FieldType.WALL: return False else: self.currentpos = new_pos return True elif self.areamap[new_pos].type != FieldType.WALL: if self.areamap[new_pos].dist < self.areamap[self.currentpos].dist-1: # we found a shorter path to the current position self.areamap[self.currentpos].update_dist(self.areamap[new_pos].dist+1) self.currentpos = new_pos return False else: return False def draw_map(self): min_x = min(x for x,y in self.areamap.keys()) max_x = max(x for x,y in self.areamap.keys()) min_y = min(y for x,y in self.areamap.keys()) max_y = max(y for x,y in self.areamap.keys()) x_range = max_x - min_x y_range = max_y - min_y full_map = "" for y in range(y_range+1): for x in range(x_range+1): position = Position(x+min_x, y+min_y) if position == self.currentpos: full_map = full_map + "D" elif position not in self.areamap: full_map = full_map + "#" elif self.areamap[position].type == FieldType.FIELD: full_map = full_map + " " elif self.areamap[position].type == FieldType.WALL: full_map = full_map + "|" elif self.areamap[position].type == FieldType.OSYS: full_map = full_map + "X" elif self.areamap[position].type == FieldType.OXY: full_map = full_map + "O" full_map = full_map + "\n" full_map = full_map + "\n" print(full_map) def traverse_grid(self): directions = [Direction.EAST, Direction.SOUTH, Direction.NORTH, Direction.WEST] steps = deque(directions) i = 0 while steps: i+=1 next_move = steps.popleft() if self.visualize: time.sleep(0.2) print("Step: %i" % i) self.draw_map() if self.move_droid(next_move): prev = opposite[next_move] steps.appendleft(prev) move_order = directions[:] move_order.remove(prev) for entry in reversed(move_order): steps.appendleft(entry) else: continue self.draw_map()
data = f.readline() input_list = data.split(',') input_prog = list(map(int, input_list)) ### PART 1 intcode_network = dict() for i in range(50): computer = IntcodeComputer(input_prog, [i], "Network Address %i" % i) intcode_network[i] = computer run_network = True while run_network: for id, computer in intcode_network.items(): print("Run computer %i" % id) computer.run_program() output = computer.get_output() print(output) if output: if output[0] == 255: run_network = False print("Silver: %i" % output[2]) break chunk_size = 3 for i in range(0, len(output), chunk_size): instruction = output[i:i + chunk_size] intcode_network[instruction[0]].add_prog_input(instruction[1:]) ### PART 2 class NAT():
#!/usr/bin/env python3 """ Advent of Code 2019 Day 9: Sensor Boost https://adventofcode.com/2019/day/9 """ from intcode import IntcodeComputer def parse_input_data(input: str) -> [int]: return [int(i) for i in input.rstrip().split(',')] if __name__ == '__main__': input_filepath = __file__.rstrip('.py') + '_input.txt' with open(input_filepath, 'r') as file: input = parse_input_data(file.read()) ic = IntcodeComputer(input, [1], logging=False) ic.run_program() part_1 = ic.output.pop(0) print(f"Solution to part 1 is: {part_1}") assert part_1 == 2682107844 ic = IntcodeComputer(input, [2], logging=False) ic.run_program() part_2 = ic.output.pop(0) print(f"Solution to part 2 is: {part_2}") assert part_2 == 34738
def to_ascii_instruction(instruction): ascii_instr = [] for char in instruction: ascii_instr.append(ord(char)) return ascii_instr def print_output(intcode_instruction): str = '' for digit in intcode_instruction: str = str + chr(digit) print(str) adventure = IntcodeComputer(input_prog, [], "Cryostasis") adventure.run_program() output = adventure.get_output() print_output(output) while not adventure.has_stopped(): get_input = input(">") input_instruction = to_ascii_instruction(get_input + "\n") adventure.add_prog_input(input_instruction) adventure.run_program() output = adventure.get_output() print_output(output) print("Game Over.")
data = f.readline() input_list = data.split(',') input_prog = list(map(int, input_list)) instruction = """NOT C J OR D T AND T J NOT A T OR T J WALK """ ascii_instr = to_ascii_instruction(instruction) springdroid = IntcodeComputer(input_prog, ascii_instr, "Spring Droid Machine") springdroid.run_program() last_moments = springdroid.get_output() #draw_last_moments(last_moments) print("Silver: %i" % last_moments[-1]) ### PART 2 print("\n PART 2 START \n") instruction = """NOT C J NOT A T OR T J NOT B T OR T J NOT D T NOT T T AND T J