def part_1(): robot = Robot(Machine(load_tape('data/11-program.txt')), debug=False) grid = defaultdict(lambda: Color.NONE) robot.paint_on(grid) draw_grid(grid) count = sum(1 for color in grid.values() if color) print(f"painted on {count} cells")
def part_2(): tape = load_tape('data/13-program.txt') tape[0] = 2 # 2 quarters cheat m = Machine(tape, debug=False) game = m.run_control() screen = [[' ' for _ in range(SCREEN_WIDTH)] for _ in range(SCREEN_HEIGHT)] score = None paddle_x = None ball_x = None def joystick(): if paddle_x is not None and ball_x is not None: return sgn(ball_x - paddle_x) else: return None try: while True: x = game.send(joystick()) y = game.send(joystick()) t = game.send(joystick()) if x == -1 and y == 0: score = t elif 0 <= x < SCREEN_WIDTH and 0 <= y < SCREEN_HEIGHT: prev = screen[y][x] screen[y][x] = TILES[t] if t == 4: ball_x = x elif prev == TILES[4]: ball_x = None if t == 3: paddle_x = x elif prev == TILES[3]: paddle_x = None if prev == TILES[2] and t != 2: print(f"destroyed ({x}, {y})") else: raise ValueError(f"out of bounds: x={x}, y{y}") if ball_x is not None and paddle_x is not None and score is not None: print() print(f"score: {score}") print('\n'.join(''.join(row) for row in screen)) # time.sleep(.05) except StopIteration: pass
def part_1(): m = Machine(load_tape('data/13-program.txt')) def load_screen(): seq = list(m.run_output_only()) for h in range(0, len(seq), 3): x, y, t = seq[h:h+3] yield Point(x, y), t screen = list(load_screen()) draw_screen(screen) blocks_count = sum(1 for p, t in screen if t == 2) print(f"part 1: blocks count is {blocks_count}")
def solution(fn: str): io = Machine(load_tape(fn)).run_io() commands = [ 'west', 'take mug', 'east', 'east', 'take coin', 'north', 'north', 'take hypercube', 'south', 'south', 'south', 'west', 'take astrolabe', 'north', 'east', 'north', 'east' ] for command in commands: print(io.read_str(), end='') print(f">>> {command}") io.write(command + "\n") print(io.read_str(), end='')
def robot_run(*lines: str) -> Optional[int]: io = Machine(load_tape("data/21-program.txt")).run_io() print(io.read_str(), end='') script = "".join(line + "\n" for line in lines) print(script, end="") io.write(script) answer = list(io.read()) if answer[-1] > 255: print(''.join(chr(v) for v in answer[:-1]), end="") return answer[-1] else: print(''.join(chr(v) for v in answer), end="") return None
def part_2(screen): tape = load_tape("data/17-program.txt") assert tape[0] == 1 tape[0] = 2 # control robot m = Machine(tape) io = m.run_io() script = """ A,A,B,C,B,C,B,C,A,C R,6,L,8,R,8 R,4,R,6,R,6,R,4,R,4 L,8,R,6,L,10,L,10 """ lines = [ line.strip() + '\n' for line in script.splitlines() if line.strip() ] assert len(lines) == 4 draw_screen(io, screen) io.write(lines[0]) # main assert io.read_str() == "Function A:\n" io.write(lines[1]) # move function A assert io.read_str() == "Function B:\n" io.write(lines[2]) # move function B assert io.read_str() == "Function C:\n" io.write(lines[3]) # move function C assert io.read_str() == "Continuous video feed?\n" io.write("y\n" if screen else "n\n") # video feed? dust = draw_screen(io, screen) print(f"dust: {dust}")
def solve(fn: str): io = Machine(load_tape(fn)).run_io() commands = [ 'west', 'take mug', 'north', 'take easter egg', 'south', 'east', 'south', 'east', 'north', 'take candy cane', 'south', 'west', 'north', 'east', 'take coin', 'north', 'north', 'take hypercube', 'south', 'east', 'take manifold', 'west', 'south', 'south', 'east', 'take pointer', 'west', 'west', 'take astrolabe', 'north', 'east', 'north' ] items = [ command[5:] for command in commands if command.startswith('take ') ] while commands: print(io.read_str(), end='') command = commands[0] del commands[0] print(f">>> {command}") io.write(command + '\n') print(io.read_str(), end='') co = generate_commands(items) commands = next(co) try: while True: last_output = None for command in commands: print(f">>> {command}") io.write(command + '\n') last_output = io.read_str() print(last_output, end='') # ... commands = co.send(int(input())) finally: pass
def part_1(): m = Machine(load_tape("data/17-program.txt")) screen_output = list(m.run_output_only()) print(screen_output) lines = [ line.strip() for line in ''.join(chr(v) for v in screen_output).splitlines() if line.strip() ] height = len(lines) width = len(lines[0]) assert all(len(line) == width for line in lines) print(f"width={width}, height={height}") def cross(x, y): yield x, y yield x + 1, y yield x - 1, y yield x, y + 1 yield x, y - 1 intersections = {(x, y) for x in range(1, width - 1) for y in range(1, height - 1) if all(lines[cy][cx] == '#' for cx, cy in cross(x, y))} print('\n'.join(''.join('O' if (x, y) in intersections else lines[y][x] for x in range(width)) for y in range(height))) alignment = sum(x * y for x, y in intersections) print("intersections:") for x, y in intersections: print(f"> {x:2}, {y:2} -> {x*y:4}") print(f"total: {alignment:5}")
def map_maze(): machine_f = Machine(load_tape("data/15-program.txt")).as_function_scalar() def sensor(heading: Heading) -> Tile: return Tile.from_code(machine_f(heading.code)) step = 0 robot = Robot(sensor) while True: step += 1 robot.step() print( f"[R] {step}: pos={robot.pos}, distance={robot.current_distance}") if robot.current_tile == Tile.OXYGEN: robot.draw_plan() print(f"oxygen source located after {step} steps: " f"pos={robot.pos}, " f"distance={robot.current_distance}") print() break # continue as different "robot" step = 0 oxbot = Robot(sensor, pos=robot.pos) while True: step += 1 oxbot.step() print( f"[O] {step}: pos={oxbot.pos}, distance={oxbot.current_distance}") if oxbot.current_tile == Tile.OXYGEN: oxbot.draw_plan() max_oxygen_distance = max(oxbot.distances.values()) print(f"max distance from oxygen source: {max_oxygen_distance}") break
assert list(m.run_output_only()) == [] value = m.memory[0] if value == target_value: return noun, verb else: return None def part_1(tape: list[int]): tape = list(tape) tape[1], tape[2] = 12, 2 m = Machine(tape) assert list(m.run_output_only()) == [] print(f"part 1: value at memory address 1 is {m.memory[0]}") def part_2(tape: list[int]): tape = list(tape) answer = find_noun_verb(tape, target_value=19690720) if answer: noun, verb = answer print(f"part 2: noun={noun}, verb={verb}") else: print(f"part 2: answer not found") if __name__ == '__main__': tape_ = load_tape("data/02-program.txt") part_1(tape_) part_2(tape_)
def part_2(): robot = Robot(Machine(load_tape('data/11-program.txt')), debug=False) grid2 = defaultdict(lambda: Color.NONE) grid2[Point(0, 0)] = Color.WHITE robot.paint_on(grid2) draw_grid(grid2)
def run_network() -> int: tape = load_tape("data/23-program.txt") def create_network_io(address: int, debug: bool = False) -> MachineIO: machine = Machine(tape, name=f"M{address:02}", debug=debug) io = machine.run_io() # this is your address io.write_single(address) # and queue is empty io.write_single(-1) return io network: list[MachineIO] = [ create_network_io(address) for address in range(50) ] queue: list[Packet] = [] nat_packet: Optional[Packet] = None nat_sent_history: list[Packet] = [] # initialize queue for address, io in enumerate(network): while io.state == IOState.OUTPUT: packet_out = Packet(*io.read(3)) queue.append(packet_out) print(f"M{address:02}:{len(queue):02} queued {packet_out}") while True: # process queue until it's empty while queue: packet = queue.pop() address = packet.address if address == 255: nat_packet = packet print(f"NAT:{len(queue):02} receiving {packet}") continue io = network[address] assert io.state == IOState.INPUT io.write(packet) print(f"M{address:02}:{len(queue):02} receiving {packet}") while io.state == IOState.OUTPUT: packet_out = Packet(*io.read(3)) queue.append(packet_out) print(f"M{address:02}:{len(queue):02} queued {packet_out}") if nat_packet: if nat_sent_history: previous_nat_packet = nat_sent_history[-1] if nat_packet.y == previous_nat_packet.y: print( f"NAT:{len(queue):02} repeating NAT packet Y detected: " f"now={nat_packet}, prev={previous_nat_packet}") return nat_packet.y nat_packet.address = 0 print( f"NAT:{len(queue):02} queue is empty, queueing {nat_packet} to M00" ) queue.append(nat_packet) nat_sent_history.append(nat_packet) nat_packet = None else: print( f"NAT:{len(queue):02} queue is empty and there's no NAT packet available" ) return -1
from y2019.intcode import load_tape from y2019.intcode import Machine if __name__ == '__main__': m = Machine(load_tape("data/09-program.txt")) result_1 = next(m.run_fixed_input([1])) print(f"part 1: {result_1}") result_2 = next(m.run_fixed_input([2])) print(f"part 2: {result_2}")
from common.file import relative_path from y2019.intcode import load_tape from y2019.intcode import Machine scan_machine = Machine( load_tape(relative_path(__file__, "data/19-program.txt"))) scan = scan_machine.as_function_scalar(restarting=True) def part_1(): total = 0 for y in range(50): line = [scan(x, y) for x in range(50)] total += sum(line) print(''.join('#' if r else '.' for r in line)) print(f"total: {total}") def find_square(y_start: int = 20, x_start: tuple[int, int] = (14, 16), square_size: int = 100, debug: bool = False) -> tuple[int, int]: y = y_start x_min, x_max = x_start assert not scan(x_min - 1, y) assert scan(x_min, y) assert scan(x_max, y) assert not scan(x_max + 1, y) xs = {y: (x_min, x_max)}