Пример #1
0
 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
Пример #2
0
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
Пример #3
0
def find_noun_verb(tape, target_value) -> Optional[tuple[int, int]]:
    for noun in range(len(tape)):
        tape[1] = noun
        for verb in range(len(tape)):
            tape[2] = verb
            m = Machine(tape)
            assert list(m.run_output_only()) == []
            value = m.memory[0]
            if value == target_value:
                return noun, verb
    else:
        return None
Пример #4
0
def find_best_phases_loop(tape: Iterable[int],
                          phases_range: range = range(5, 10),
                          debug=False):
    amps = [
        Machine(tape, name=f"Amp {n+1}", debug=debug)
        for n in range(len(phases_range))
    ]

    def run_amps_loop(phases: list[int]) -> Optional[int]:
        amp_fs = [
            amp.as_function_scalar(init=[phase])
            for amp, phase in zip(amps, phases)
        ]
        signal = 0
        final_signal = None
        while True:
            try:
                for amp_f in amp_fs:
                    signal = amp_f(signal)
                final_signal = signal
            except StopIteration:
                return final_signal

    best_phases = max(permutations(phases_range), key=run_amps_loop)
    best_signal = run_amps_loop(best_phases)
    print(f"best: {best_phases} -> {best_signal}")
    return best_phases, best_signal
Пример #5
0
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")
Пример #6
0
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}")
Пример #7
0
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}")
Пример #8
0
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}")
Пример #9
0
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
Пример #10
0
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='')
Пример #11
0
def find_best_phases(tape: Iterable[int],
                     phases_range: range = range(5),
                     debug=False):
    amps = [
        Machine(tape, name=f"Amp {n+1}", debug=debug)
        for n in range(len(phases_range))
    ]

    def run_amps(phases):
        signal = 0
        for amp, phase in zip(amps, phases):
            amp_f = amp.as_function_scalar(init=[phase])
            signal = amp_f(signal)
        # print(f"{phases} -> {signal}")
        return signal

    best_phases = max(permutations(phases_range), key=run_amps)
    best_signal = run_amps(best_phases)
    print(f"best: {best_phases} -> {best_signal}")
    return best_phases, best_signal
Пример #12
0
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
Пример #13
0
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
Пример #14
0
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]}")
Пример #15
0
 def __init__(self, machine: Machine, debug: bool = False):
     self.brain = machine.as_function()
     self.pos = Point(0, 0)
     self.heading = Heading.NORTH
     self.debug = debug
Пример #16
0
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)
Пример #17
0
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)}
Пример #18
0
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}")