def get_cell(self, x: int, y: int) -> bool: if (x, y) in self.beam_spaces: return self.beam_spaces[(x, y)] program = Program(self.program_data[:]) program.send_input(x) program.send_input(y) pulled = bool(program.next_output()) self.beam_spaces[(x, y)] = pulled return pulled
def run(program: Program, input_data: Deque[str]) -> None: bf_door = brute_force_door() for line in program.read_lines(): print(line) if line == "Command?": if input_data: command = input_data.popleft() else: command = next(bf_door) print(command) program.write_string(command)
def main() -> None: with open(INPUT, "r") as fin: program_data = [int(x) for x in fin.readline().strip().split(",")] part1 = False computers = [Program(program_data[:], [i]) for i in range(50)] last_nat = None nat_history: Set[int] = set() while True: idle = True for computer in computers: computer.send_input(-1) output = chain(computer.consume_all_input(), computer.run_until_input()) for address, x, y in zip(output, output, output): if address == 255: if not part1: print(y) part1 = True last_nat = (x, y) else: computers[address].send_input(x) computers[address].send_input(y) idle = False if idle: assert last_nat is not None x, y = last_nat if y in nat_history: print(y) break nat_history.add(y) computers[0].send_input(x) computers[0].send_input(y)
def main() -> None: with open(INPUT, "r") as fin: program = [int(x) for x in fin.readline().strip().split(",")] max_output = None for order in itertools.permutations(range(5)): signal = 0 for phase_setting in order: result = run(program[:], [phase_setting, signal]) if result is None: raise Exception("No return value") signal = result max_output = signal if max_output is None else max(signal, max_output) print(max_output) max_output = None for order in itertools.permutations(range(5, 10)): signal = 0 current_amplifier = 0 amplifiers = [] for phase_setting in order: p = Program(program[:], [phase_setting]) amplifiers.append(p) while True: amplifiers[current_amplifier].send_input(signal) new_signal = amplifiers[current_amplifier].next_output_or_end() if new_signal is None: break signal = new_signal current_amplifier = (current_amplifier + 1) % len(amplifiers) max_output = signal if max_output is None else max(signal, max_output) print(max_output)
def read_image(program: Program) -> str: result: List[str] = [] for line in program.read_lines(): if not line.strip(): return "\n".join(result) result.append(line) raise Exception("Expected blank line")
def main() -> None: with open(INPUT, "r") as fin: program_data = [int(x) for x in fin.readline().split(",")] program_data[0] = 2 program = Program(program_data) board = Board() for x, y, tile in zip(program, program, program): if x == -1: break board.set_tile(x, y, Tile(tile)) print(board) while True: output = program.run_until_input() for x, y, val in zip(output, output, output): if x == -1 and y == 0: board.score = val else: board.set_tile(x, y, Tile(val)) print(board) if program.ended: break program.send_input(board.next_move()) program.next_command() print(board)
def run(program: Program, commands: List[str]) -> Optional[int]: print(program.read_line()) for c in commands: program.write_string(c) print(program.read_line()) print(program.read_line()) print(program.read_line()) ret = next(program) if ret == 10: for line in program.read_lines(): print(line) return None return ret
def run(program_data: List[int], white_start: bool) -> Dict[Tuple[int, int], bool]: robot = Robot() program = Program(program_data) tiles: Dict[Tuple[int, int], bool] = defaultdict(bool) if white_start: tiles[(0, 0)] = True while True: color = int(tiles.get(robot.pos, False)) program.send_input(color) new_color = program.next_output_or_end() if new_color is None: return tiles turn = program.next_output() tiles[robot.pos] = bool(new_color) robot.rotate(True if turn == 1 else False) robot.move()
def __init__(self, program: List[int]) -> None: self.position = Point(0, 0) self.program = Program(program) self.status: Optional[Status] = None self.grid = defaultdict(lambda: Cell.Unknown, {Point(0, 0): Cell.Floor}) self.to_explore = deque([p for p, m in neighbours(self.position)])
class Robot: def __init__(self, program: List[int]) -> None: self.position = Point(0, 0) self.program = Program(program) self.status: Optional[Status] = None self.grid = defaultdict(lambda: Cell.Unknown, {Point(0, 0): Cell.Floor}) self.to_explore = deque([p for p, m in neighbours(self.position)]) def move(self, move: Movement) -> None: vector = VECTORS[move] self.program.send_input(move.value) self.status = Status(self.program.next_output()) if self.status == Status.Wall: self.grid[self.position + vector] = Cell.Wall else: self.position += vector self.grid[self.position] = Cell.Floor if self.status == Status.Moved else Cell.Oxygen def search(self) -> Point: while self.to_explore: print(self) to_explore = self.to_explore.popleft() for movement in self.shortest_path(self.position, to_explore): self.move(movement) if self.status != Status.Wall: self.to_explore.extend([p for p, m in neighbours(self.position) if self.grid[p] == Cell.Unknown]) if self.status == Status.Oxygen: oxygen_position = self.position return oxygen_position def shortest_path(self, start: Point, end: Point) -> List[Movement]: visited = set() to_visit: Deque[Tuple[Point, List[Movement]]] = deque([(start, [])]) while True: pos, path = to_visit.popleft() if pos == end: return path if pos not in visited and self.grid[pos] in {Cell.Floor, Cell.Oxygen}: for neighbour, movement in neighbours(pos): to_visit.append((neighbour, path + [movement])) visited.add(pos) def spread_oxygen(self, start: Point) -> int: turn_count = 0 to_visit = {start} while True: print(self) to_visit = {n for p in to_visit for n, m in neighbours(p) if self.grid[n] == Cell.Floor} self.grid.update({n: Cell.Oxygen for n in to_visit}) if not to_visit: break turn_count += 1 return turn_count def __str__(self) -> str: min_x, max_x, min_y, max_y = borders(self.grid.keys()) result = [] for y in range(min_y, max_y + 1): result.append("".join(str(self.grid[Point(x, y)]) if Point(x, y) != self.position else "D" for x in range(min_x, max_x + 1))) return "\n".join(result)
def main() -> None: with open(INPUT, "r") as fin: program_data = [int(x) for x in fin.readline().strip().split(",")] print(run(Program(program_data[:]), part1)) print(run(Program(program_data[:]), part2))
def main() -> None: with open(INPUT, "r") as fin: program_data = [int(x) for x in fin.readline().strip().split(",")] run(Program(program_data), deque(START_COMMANDS))
def main() -> None: with open(INPUT, "r") as fin: program_data = [int(c) for c in fin.readline().strip().split(",")] program_data[0] = 2 program = Program(program_data[:]) image = read_image(program) print(image) intersections = find_intersections(image) print(sum(x * y for x, y in intersections)) program.read_line() program.write_string("A,A,B,C,C,A,C,B,C,B") program.read_line() program.write_string("L,4,L,4,L,6,R,10,L,6") program.read_line() program.write_string("L,12,L,6,R,10,L,6") program.read_line() program.write_string("R,8,R,10,L,6") program.read_line() program.write_string("n") next(program) image = read_image(program) print(image) print(next(program))