def goto_pos(steps): """Returns machine accepting next step inputs""" machine = run_async(prog) for s in steps: machine.send(None) machine.send(STEP_TO_COMMAND[s]) return machine
def play_interactive(): grid = [[' '] * 40 for _ in range(25)] prog = parse_input(day=13) prog[0] = 2 machine = run_async(prog) out = None score = 0 try: restore = termios.tcgetattr(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) while True: out = machine.send(out) # We get some output if out is not None: x = out y = next(machine) t = next(machine) if x < 0: score = t else: grid[y][x] = GLYPHS.get(t, '?') else: print("\033[2J\033[1;1H") print(f"Score: {score}") print("\n".join(''.join(r) for r in grid)) out = get_input() sleep(0.2) except StopIteration: print("\033[33mGAME OVER\033[m") finally: termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, restore)
def level2(): prog = get_prog() prog[0] = 2 machine = run_async(prog) # Print initial map outputs = [] out = machine.send(None) while out: outputs.append(chr(out)) out = next(machine) print("".join(outputs)) for c in MAIN: machine.send(c) outputs = [] out = machine.send(ord('\n')) while out: outputs.append(chr(out)) out = next(machine) print("".join(outputs)) for instr in ROUTINES[ord('A')]: machine.send(instr) outputs = [] out = machine.send(ord('\n')) while out: outputs.append(chr(out)) out = next(machine) print("".join(outputs)) for instr in ROUTINES[ord('B')]: machine.send(instr) outputs = [] out = machine.send(ord('\n')) while out: outputs.append(chr(out)) out = next(machine) print("".join(outputs)) for instr in ROUTINES[ord('C')]: machine.send(instr) outputs = [] out = machine.send(ord('\n')) while out: outputs.append(chr(out)) out = next(machine) print("".join(outputs)) machine.send(ord('y')) outputs = [] out = machine.send(ord('\n')) while out and out < 255: outputs.append(chr(out)) out = next(machine) frames = "".join(outputs).split('\n\n') for f in frames: print("\033[2J\033[1;1H") print(f) sleep(0.1) print(out)
def run_interactive(instr, speed=1): machine = run_async(prog) print(ascii_to_str(read_output(machine))) print(instr) out = feed_input(machine, [ord(c) for c in instr]) buff = read_output(machine, [out]) s = ascii_to_str(buff) frames = s.split("\n\n") animate_frames(frames, speed)
def animate(): prog = parse_input() frames = drive_robot(run_async(prog), initial=1, return_frames=True) (final, _, _) = frames[-1] xmin = min(x for (x, y) in final) xmax = max(x for (x, y) in final) ymin = min(y for (x, y) in final) ymax = max(y for (x, y) in final) #import pdb; pdb.set_trace() for (grid, robot, direction) in frames: # Clear screen and move cursor to top-left print("\033[2J\033[1;1H") print(draw(grid, xmin, xmax, ymin, ymax, robot, direction)) sleep(0.1)
def level1(): prog = parse_input(day=13) machine = run_async(prog) outputs = list(machine) blocks = set() for i in range(0, len(outputs), 3): x, y, t = outputs[i:i + 3] if t == 2: blocks.add((x, y)) elif t == 4: try: blocks.remove((x, y)) except KeyError: pass print(len(blocks))
def level2(): phases = permutations(range(5, 10), 5) max_output = 0 max_config = None for config in phases: amps = [run_async(prog) for l in "ABCDE"] initial = list(reversed(config)) inpt = output = 0 try: for amp in cycle(amps): amp.send(None) if initial: amp.send(initial.pop()) inpt = amp.send(inpt) except StopIteration: output = inpt if output >= max_output: max_output, max_config = output, config print(f"Max thruster signal {max_output} " f"for configuration {','.join(str(i) for i in max_config)}")
def level2(): grid = [[' '] * 40 for _ in range(25)] prog = parse_input(day=13) prog[0] = 2 machine = run_async(prog) out = None score = 0 pad_x = 0 ball_x = 0 print("\033[2J") try: while True: out = machine.send(out) # We got some output if out is not None: x = out y = next(machine) t = next(machine) if x < 0: score = t else: # Pad if t == 3: pad_x = x elif t == 4: ball_x = x grid[y][x] = GLYPHS.get(t, '?') else: if pad_x == ball_x: out = 0 elif pad_x < ball_x: out = 1 else: out = -1 print("\033[1;1H") print(f"Score: {score}") print("\n".join(''.join(r) for r in grid)) sleep(0.2) except StopIteration: print("\033[33mGAME FINISHED\033[m") print(f"Final score: {score}")
def drive_robot(interactive=True): machine = run_async(prog) # Droid coordinates x, y = W // 2, H // 2 free_spots = set() walls = set() oxygen = None next_move = None success = False try: # import pudb; pudb.set_trace() while True: display((x, y), free_spots, walls, oxygen) free_spots.add((x, y)) report = machine.send(next_move) if report is None: if interactive: next_move = get_input() else: sleep(0.01) next_move = guess_input(next_move, success) else: dx, dy = DIRECTIONS[next_move] next_pos = x + dx, y + dy success = report != WALL_HIT if report == MOVE_SUCCESSFUL: x, y = next_pos elif report == OXYGEN_FOUND: oxygen = x, y = next_pos elif report == WALL_HIT: walls.add(next_pos) else: raise RuntimeError("Unknown report code:", report) raise StopIteration("Oxygen: {oxygen}") except StopIteration: print('Oxygen not found')
def step2(): prog = parse_input() grid = drive_robot(run_async(prog), initial=1) return draw(grid)
def step1(): prog = parse_input() grid = drive_robot(run_async(prog)) return len(grid)
from day05 import run_async def run_until_complete(machine, inputs=None): if inputs is None: inputs = [] inputs = inputs[::-1] outputs = [] out = None try: while True: out = machine.send(out) if out is None: out = inputs.pop() else: outputs.append(out) except StopIteration: return outputs with open('data/day09.txt') as f: prog = [int(i) for i in f.read().strip().split(',')] machine = run_async(prog) print(run_until_complete(machine, inputs=[2]))
def is_pulled(x, y): machine = run_async(prog) next(machine) machine.send(x) return machine.send(y)
def get_input_string(): with open("data/day17.txt") as f: prog = [int(i) for i in f.read().strip().split(',')] return "".join([chr(i) for i in run_async(prog)])