def __init__(self): self.comp = Computer(output_to_screen=False) self.comp.load_file('input.txt') self.screen = {} # Key= vertex (x, y), Value= character at that vertex. self.max_x, self.max_y = 0, 0 # Edge positions of the screen. self.robot_pos = (0, 0) # Current position of the robot. self.robot_direction = 'N' # N, E, S, or W. self.robot_trail = [] # Steps that the robot has taken. self.dx = {'N': 0, 'E': 1, 'S': 0, 'W': -1} self.dy = {'N': -1, 'E': 0, 'S': 1, 'W': 0}
# Part of solution to day 21 of AOC 2019, "Springdroid Adventure". # https://adventofcode.com/2019/day/21 from dict_computer import Computer comp = Computer(output_to_screen=False) comp.load_file('input.txt') comp.input_from_keyboard = False send_to_input = """NOT A J NOT C T AND H T OR T J NOT B T AND A T AND C T OR T J AND D J RUN """ input_pos = 0 comp.input = ord(send_to_input[input_pos]) while not comp.halted: comp.run_until_io() # If paused due to output, turn the output into a char and send to stdout.
class Ascii: def __init__(self): self.comp = Computer(output_to_screen=False) self.comp.load_file('input.txt') self.screen = {} # Key= vertex (x, y), Value= character at that vertex. self.max_x, self.max_y = 0, 0 # Edge positions of the screen. self.robot_pos = (0, 0) # Current position of the robot. self.robot_direction = 'N' # N, E, S, or W. self.robot_trail = [] # Steps that the robot has taken. self.dx = {'N': 0, 'E': 1, 'S': 0, 'W': -1} self.dy = {'N': -1, 'E': 0, 'S': 1, 'W': 0} def find_screen_edges(self): """Find the maximum x, and maximum y dimensions of the screen.""" for (x, y) in self.screen: if x > self.max_x: self.max_x = x if y > self.max_y: self.max_y = y def find_robot(self): """Look at all positions on the screen for the robot (caret character).""" for (x, y) in self.screen: if self.screen[(x, y)] == '^': self.robot_pos = (x, y) def refresh_screen(self): """Run the computer, loading its output into the screen buffer.""" x, y = 0, 0 while not self.comp.halted and not self.comp.input_from_keyboard: self.comp.run_until_output() if self.comp.output == 10: # "10 starts a new line of output below the current one..." x = 0 y += 1 else: self.screen[(x, y)] = chr(self.comp.output) x += 1 self.find_screen_edges() self.find_robot() def load_test_screen(self, filename: str): """Load a test screen from parm file.""" f = open(filename, 'r') whole_text = f.read() x, y, = 0, 0 for each_char in whole_text: if each_char == '\n': # Newline. x = 0 y += 1 else: self.screen[(x, y)] = each_char x += 1 f.close() self.find_screen_edges() self.find_robot() def render_screen(self): """Render the screen buffer to stdout.""" for y in range(self.max_y + 1): for x in range(self.max_x + 1): print(self.screen[x, y], end='') print() def is_intersection(self, test_vertex: (int, int)) -> bool: """Is there an intersection at parm vertex?""" # Intersections are the centre of patterns like this, # .#. # ### # .#. (test_x, test_y) = test_vertex # print(test_x, test_y) # Check that the test vertex is far enough from edges to be an intersection. if test_x == 0 or test_x == self.max_x or test_y == 0 or test_y == self.max_y: return False lookup = {(-1, -1): '.', (0, -1): '#', (1, -1): '.', (-1, 0): '#', (0, 0): '#', (1, 0): '#', (-1, 1): '.', (0, 1): '#', (1, 1): '.'} for check in lookup: (dx, dy) = check # print(check, lookup[check], self.screen[(test_x + dx, test_y + dy)]) # Every lookup must match the expected value, otherwise it is not an intersection. if self.screen[(test_x + dx, test_y + dy)] != lookup[check]: return False # All tests passed, so it must be an intersection. return True def turn_right(self): """Rotate robot clockwise.""" self.robot_direction = {'N': 'E', 'E': 'S', 'S': 'W', 'W': 'N'}[self.robot_direction] self.robot_trail.append('R') def turn_left(self): """Rotate robot anticlockwise.""" self.robot_direction = {'N': 'W', 'W': 'S', 'S': 'E', 'E': 'N'}[self.robot_direction] self.robot_trail.append('L') def can_walk_one_step(self) -> bool: """Can the robot walk ahead 1 step without going off edge of scaffolding.""" (x, y) = self.robot_pos # Check for going off edge of screen. if self.robot_direction == 'N' and y == 0: return False if self.robot_direction == 'W' and x == 0: return False if self.robot_direction == 'S' and y == self.max_y: return False if self.robot_direction == 'E' and x == self.max_x: return False test_pos = (x + self.dx[self.robot_direction], y + self.dy[self.robot_direction]) if self.screen[test_pos] != '#': return False return True def forward(self): """Move forward until next step would be off edge of scaffolding.""" step_count = 0 while self.can_walk_one_step(): (x, y) = self.robot_pos self.robot_pos = (x + self.dx[self.robot_direction], y + self.dy[self.robot_direction]) step_count += 1 self.robot_trail.append(str(step_count)) def on_screen(self, test_vertex: (int, int)) -> bool: """Is the parm vertex within the boundaries of the screen?""" (test_x, test_y) = test_vertex if test_x < 0 or test_x > self.max_x or test_y < 0 or test_y > self.max_y: return False return True def seek(self) -> bool: """Robot has reached end of current straight bit of scaffolding. So, look left and right for next bit. Return false if a new direction to travel wasn't found.""" (x, y) = self.robot_pos seek_left = () seek_right = () if self.robot_direction == 'N': seek_left = (x - 1, y) seek_right = (x + 1, y) if self.robot_direction == 'E': seek_left = (x, y - 1) seek_right = (x, y + 1) if self.robot_direction == 'S': seek_left = (x + 1, y) seek_right = (x - 1, y) if self.robot_direction == 'W': seek_left = (x, y + 1) seek_right = (x, y - 1) if self.on_screen(test_vertex=seek_left): if self.screen[seek_left] == '#': self.turn_left() return True if self.on_screen(test_vertex=seek_right): if self.screen[seek_right] == '#': self.turn_right() return True
# Part of solution to day 19 of AOC 2019, "Tractor Beam". # https://adventofcode.com/2019/day/19 from dict_computer import Computer # "How many points are affected by the tractor beam in the 50x50 area closest to the emitter? # (For each of X and Y, this will be 0 through 49.) points = 0 for y in range(50): for x in range(50): this_comp = Computer(output_to_screen=False) this_comp.load_file('input.txt') this_comp.input = x this_comp.run_until_io() this_comp.input = y this_comp.run() if this_comp.output == 1: points += 1 print(this_comp.output, end='') print() print('Part 1:', points)