def parsed(data): comp = IntComputer(data) comp.run() txt = "".join([chr(x) for x in reversed(comp.output)]) grid = ZGrid(txt) grid.draw() return grid
class Q15AStar(AStar): def __init__(self, data): self.grid = ZGrid({0j: "."}) self.comp = IntComputer(data) self.comp.output = deque(maxlen=1) self.freezer = {0j: self.comp.freeze()} state0 = 0j AStar.__init__(self, state0, None) def adjacent(self, z): self.comp.unfreeze(self.freezer[z]) for dz, input_val in neighbours.items(): self.comp.input.append(input_val) self.comp.run(until=IntComputer.op_output) [rc] = self.comp.output if rc == NACK: self.grid[z + dz] = "#" else: self.grid[z + dz] = "." self.freezer[z + dz] = self.comp.freeze() back = neighbours[-dz] self.comp.input.append(back) self.comp.run(until=IntComputer.op_output) assert self.comp.output[0] if rc == GOAL: self.target = z + dz yield z + dz def draw(self): overlay = {0: "O"} if self.target is not None: overlay[self.target] = "T" self.grid.draw(overlay=overlay)
def launch(dx, dy, draw=False): x = y = y_max = 0 xys = [] while y >= y0 and x <= x1: x += dx y += dy xys.append((x, y)) dx -= 1 if dx > 0 else -1 if dx < 0 else 0 # drag dy -= 1 # gravity y_max = max(y_max, y) if (x, y) in target_area: if draw: grid = ZGrid({0: "S"} | {complex(*z): "T" for z in target_area}) grid.draw(flip="y", overlay={complex(*xy): "#" for xy in xys}) return y_max
print("populating 50x50 zgrid...") grid = ZGrid() x0 = 0 for y in range(50): on = False for x in range(x0, 50): z = x + y*1j val = grid[z] = beam(z) if not on and val: on = True x0 = x if x0: m = y / x0 if on and not val: break grid.draw() print("part a", sum(grid.values())) def left_edge_of_beam(y, gradient): x = int(y / gradient) z = x + y*1j if beam(z): while beam(z - 1): z -= 1 else: while not beam(z + 1): z += 1 z += 1 assert beam(z) and not beam(z - 1) return z