Beispiel #1
0
def explore():
    memory = utils.get_input(__file__)[0]
    droid = intcode.Program(memory, output_mode=intcode.OutputMode.PIPE)

    oxygen = None
    graph = nx.Graph()
    queue = collections.deque()

    graph.add_node((0, 0), type=PositionType.EMPTY)
    queue.append(((0, 0), droid.copy()))

    while queue:
        node, droid = queue.popleft()
        for vector, direction in VECTORS.items():
            neighbor = tuple(np.array(node) + vector)
            if neighbor not in graph.nodes:
                droid_copy = droid.copy()
                status, _ = droid_copy.run(direction.value)
                status = Status(status)
                graph.add_node(neighbor)
                graph.add_edge(node, neighbor)

                if status == Status.WALL_HIT:
                    graph.nodes[neighbor]['type'] = PositionType.WALL
                    continue
                elif status == Status.OXYGEN_FOUND:
                    graph.nodes[neighbor]['type'] = PositionType.OXYGEN
                    oxygen = neighbor
                else:
                    graph.nodes[neighbor]['type'] = PositionType.EMPTY

                queue.append((neighbor, droid_copy))

    return graph, oxygen
Beispiel #2
0
def paint(program_memory,
          initial_position=(0, 0),
          initial_direction=Direction.UP,
          initial_color=Color.BLACK):
    curr_panel = Panel(initial_position, color=initial_color)
    curr_direction = initial_direction
    painted_panels = {}
    program = intcode.Program(program_memory,
                              output_mode=intcode.OutputMode.PIPE)

    while True:
        program.add_inputs(curr_panel.color.value)
        new_color, return_signal = program.run()
        if return_signal == intcode.ReturnSignal.RETURN_AND_HALT:
            break

        curr_panel.color = Color(new_color)
        painted_panels[curr_panel.position] = curr_panel

        rotation, return_signal = program.run()
        new_position, new_direction = move(curr_panel.position, curr_direction,
                                           Rotation(rotation))
        new_panel = painted_panels.get(new_position, Panel(new_position))

        curr_panel = new_panel
        curr_direction = new_direction

        assert return_signal == intcode.ReturnSignal.RETURN_AND_WAIT

    return painted_panels
Beispiel #3
0
def part_2():
    # Designed by inspection; look at the full path (or at least what seems like the
    # reasonable full path), and do substring matching to try and get 3 substrings that
    # generate the entire path (as long as the paths are short enough so that their
    # function length with commas is < 20); there's likely some compression algorithm
    # that can do this automatically but I don't know anything about those
    main_routine = ['A,B,A,C,A,B,C,B,C,B']
    function_a = ['R,8,L,10,L,12,R,4']
    function_b = ['R,8,L,12,R,4,R,4']
    function_c = ['R,8,L,10,R,8']
    print_output = ['n']

    commands = main_routine + function_a + function_b + function_c + print_output
    assert max(len(command) for command in commands) <= MAX_ROUTINE_SIZE

    memory = utils.get_input(__file__)[0]
    memory[0] = 2
    program = intcode.Program(
        memory,
        initial_inputs=intcode.commands_to_input(commands),
        output_mode=intcode.OutputMode.BUFFER,
    )

    output = program.run_until_halt()
    view = get_view(program)
    view.display()

    print(output)
Beispiel #4
0
def run_program(noun, verb):
    memory = utils.get_input(__file__)[0]
    memory[1] = noun
    memory[2] = verb
    program = intcode.Program(memory)
    program.run()
    return program.memory[0]
Beispiel #5
0
def run_commands(commands):
    memory = utils.get_input(__file__)[0]
    program = intcode.Program(
        memory,
        initial_inputs=intcode.commands_to_input(commands),
        output_mode=intcode.OutputMode.BUFFER,
    )
    program.run_until_halt()
    for output in program.yield_outputs():
        try:
            print(chr(output), end='')
        except ValueError:
            print(output)
Beispiel #6
0
def part_1():
    memory = utils.get_input(__file__)[0]
    program = intcode.Program(memory, output_mode=intcode.OutputMode.BUFFER)
    program.run_until_halt()
    view = get_view(program)
    view.display()

    alignment = 0
    for scaffold in view.scaffolds:
        if all(neighbor in view.scaffolds for neighbor in get_neighbors(scaffold)):
            alignment += get_alignment(scaffold)

    print(alignment)
Beispiel #7
0
def part_1():
    memory = utils.get_input(__file__)[0]
    beam = 0
    points = {}
    for x in range(50):
        for y in range(50):
            program = intcode.Program(memory,
                                      initial_inputs=[x, y],
                                      output_mode=intcode.OutputMode.BUFFER)
            output = program.run_until_halt()
            points[(x, y)] = output
            beam += output

    print(beam)
Beispiel #8
0
def run_thrusters(memory, phase_settings, loop):
    programs = [
        intcode.Program(memory[:], initial_inputs=[phase_setting], output_mode=intcode.OutputMode.PIPE)
        for phase_setting in phase_settings
    ]
    signal = 0
    halt_loop = False

    while not halt_loop:
        for program in programs:
            signal, exit_signal = program.run(signal)
            halt_loop = exit_signal == intcode.ReturnSignal.RETURN_AND_HALT

        if not loop:
            break

    return signal
Beispiel #9
0
def run(commands=None):
    memory = utils.get_input(__file__)[0]
    initial_inputs = intcode.commands_to_input(commands or [])
    program = intcode.Program(memory,
                              initial_inputs=initial_inputs,
                              output_mode=intcode.OutputMode.BUFFER)

    while True:
        _, return_signal = program.run()
        for output in program.yield_outputs():
            try:
                print(chr(output), end='')
            except ValueError:
                print(output)

        if return_signal == intcode.ReturnSignal.AWAITING_INPUT:
            # Run in interactive mode if more commands needed
            program.add_inputs(*intcode.commands_to_input([input()]))
        elif return_signal == intcode.ReturnSignal.RETURN_AND_HALT:
            return
        else:
            raise Exception(f'Unexpected return signal {return_signal}')
Beispiel #10
0
def get_computer(i):
    memory = utils.get_input(__file__)[0]
    # Bootstrap computers with initial input of -1, since no packets
    # are received prior to the first round
    program = intcode.Program(memory, initial_inputs=[i, -1], output_mode=intcode.OutputMode.BUFFER)
    return program
Beispiel #11
0
def play(quarters=0):
    memory = utils.get_input(__file__)[0]
    program = intcode.Program(memory, output_mode=intcode.OutputMode.BUFFER)
    game = Game(program)
    game.play(quarters=quarters)
    return game
Beispiel #12
0
def part_2():
    memory = utils.get_input(__file__)[0]
    intcode.Program(memory).run(2)
Beispiel #13
0
def get_output(memory, x, y):
    program = intcode.Program(memory,
                              initial_inputs=[x, y],
                              output_mode=intcode.OutputMode.BUFFER)
    output = program.run_until_halt()
    return output