def _run_program(robot, program): computer = Computer(program) computer.write(robot.camera()) while not computer.is_halted: computer.step() if computer.num_outputs == 2: robot.paint(computer.read()) robot.move(computer.read()) computer.write(robot.camera())
def _run_program_animated(robot, program): grid = gk.create_grid(6, 43, "Painting Robot") gk.start() computer = Computer(program) computer.write(robot.camera()) _draw(grid, robot) input("Press enter to begin...") while not computer.is_halted: computer.step() if computer.num_outputs == 2: robot.paint(computer.read()) robot.move(computer.read()) computer.write(robot.camera()) _draw(grid, robot) gk.next_frame() input("Press any key to finish...") gk.stop()
def animate(self, program, robot): """ Animate the routine """ labels = self._animation_labels(robot) program = program.copy() program[0] = 2 computer = Computer(program) while not computer.needs_input: computer.step() for char in "".join(self) + "y\n": computer.write(ord(char)) gk.start() rows = 37 cols = 45 grid = gk.create_grid(rows, cols, "Vacuum Robot") grid.map_color('.', gk.Colors.Navy) grid.map_color('#', gk.Colors.Gray) grid.map_color('A', gk.Colors.Red) grid.map_color('B', gk.Colors.Green) grid.map_color('C', gk.Colors.Blue) lines = [[' '] * cols for _ in range(rows)] row = 0 col = 0 frame = -2 input("Press enter to begin animation...") while not computer.is_halted: while not computer.num_outputs: computer.step() val = computer.read() if val < 255: if val == ord('\n'): if col: row += 1 col = 0 else: self.draw(grid, lines, labels, frame) row = 0 col = 0 frame += 1 else: lines[row][col] = chr(val) col += 1 self.draw(grid, lines, labels, frame) gk.stop()
def _part1(program, verbose=False): max_value = 0 for settings in itertools.permutations([0, 1, 2, 3, 4]): value = 0 for setting in settings: computer = Computer(program) computer.run(inputs=[setting, value]) value = computer.read() if value > max_value: if verbose: print("new max:", settings, value) max_value = value print("Part 1:", max_value)
def _ascii(program): computer = Computer(program) last = None output = StringIO() while not computer.is_halted: while not computer.num_outputs: computer.step() tile = chr(computer.read()) if last == tile == '\n': break last = tile output.write(tile) sys.stdout.write(tile) return output.getvalue()
def run(self, program): """ Run the movement routine on the robot """ program = program.copy() program[0] = 2 computer = Computer(program) while not computer.needs_input: computer.step() for char in "".join(self) + "n\n": computer.write(ord(char)) val = None while not computer.is_halted: while not computer.num_outputs: computer.step() val = computer.read() if val < 255: sys.stdout.write(chr(val)) return val
class RepairDrone: """ Represents the repair drone """ def __init__(self, program, move_cb=None): self._cpu = Computer(program) self.location = Vector(0, 0) self._empty = set() self._walls = set() self._oxygen_system = None self._move_cb = move_cb def explore(self): """ Explore the sector. Returns: a sector map """ locs = [self.location] iteration = 0 self._walls = set() self._empty = set() self._oxygen_system = None while locs: loc = locs.pop() iteration += 1 if loc in self._walls or loc in self._empty: continue if iteration % 100 == 0: print("robot at", loc, len(locs), len(self._walls)) status = self.move_to(loc) if status == Status.Wall: self._walls.add(loc) continue assert self.location == loc if status == Status.OxygenSystem: print(loc, "is the oxygen system") self._oxygen_system = loc self._empty.add(loc) locs.extend(loc.neighbors()) return Sector(self._walls, self._empty, self._oxygen_system) def move(self, direction): """ Move the drone in the specified direction """ self.location += direction if self._move_cb: self._move_cb(self.location, self._walls, self._empty, self._oxygen_system) def find_shortest_path(self, location): """ Find the shortest path to a location """ start = self.location goal = location return a_star(start, goal, Neighbors(self._empty | {location})) def move_to(self, location): """ Move to the specified location """ if (location - self.location).length == 1: commands = [_to_command(location - self.location)] else: path = self.find_shortest_path(location) commands = [ _to_command(pos1 - pos0) for pos0, pos1 in zip(path[:-1], path[1:]) ] status = Status.Empty for command in commands: while not self._cpu.needs_input: self._cpu.step() self._cpu.write(command) while not self._cpu.num_outputs: self._cpu.step() status = self._cpu.read() if status != Status.Wall: self.move(Directions[command - 1]) return Status(status)