Esempio n. 1
0
def run_program(computer: Computer) -> bool:
    try:
        computer.run()
        return True
    except Exception as e:
        print(str(e))
        return False
def find_phase_sequence(registers: List[int],
                        amplifiers: int) -> Tuple[Tuple[int, ...], int]:
    # Python libraries help me cheat in generating permutations :D
    sequence_scores = {x: None for x in permutations(range(amplifiers))}

    for curr_sequence in sequence_scores.keys():
        input_val = 0
        for amp_number in range(amplifiers):
            comp = Computer(copy_registers(registers),
                            inputs=[curr_sequence[amp_number], input_val])
            outputs = comp.run()
            input_val = outputs[0]
        sequence_scores[curr_sequence] = input_val

    return max([(k, v) for k, v in sequence_scores.items()],
               key=lambda x: x[1])
def find_phase_sequence(registers: List[int], amplifiers: int) -> Tuple[Tuple[int, ...], int]:
    sequence_scores = {x: None for x in permutations(range(amplifiers, amplifiers * 2))}

    for curr_sequence in sequence_scores.keys():

        # Instantiate the computers
        computers = [Computer(copy_registers(registers), inputs=[curr_sequence[amp_number]])
                     for amp_number in range(amplifiers)]

        # Track their outputs
        outputs = {i: [] for i in range(amplifiers)}

        # Starting from the first amplifier, feed in the appropriate input and run until producing an output.
        # Then move to the next amplifier in the loop, feeding that output as the next input.  Continue until
        # the final amplifier halts, then read the final input value from the last amplifier
        curr_computer = 0
        input_val = 0
        while True:
            computers[curr_computer].inputs.append(input_val)
            input_val = computers[curr_computer].run_until_output()

            # Getting a value of None back from Computer.run_until_output() indicates that the program halted
            if input_val is None:
                if curr_computer == amplifiers - 1:
                    break
            else:
                outputs[curr_computer].append(input_val)
            curr_computer = (curr_computer + 1) % amplifiers

        sequence_scores[curr_sequence] = outputs[amplifiers - 1][-1]

    return max([(k, v) for k, v in sequence_scores.items()], key=lambda x: x[1])
Esempio n. 4
0
def run_painting(computer: Computer,
                 start_color: int) -> Dict[Tuple[int, int], int]:
    robot_coord = (0, 0)
    direction = (0, -1)
    surface = dict()
    computer.inputs.append(start_color)
    while True:
        color = computer.run_until_output()
        if color is None:
            break
        surface[robot_coord] = color

        turn_direction = computer.run_until_output()
        if turn_direction is None:
            break
        direction = turn(direction, turn_direction)
        robot_coord = tuple(
            (robot_coord[0] + direction[0], robot_coord[1] + direction[1]))

        computer.inputs.append(get_surface_color(surface, robot_coord))

    return surface
def load() -> List[int]:
    with open("input/input07.txt", "r") as f:
        return Computer.parse_registers(f.read())
Esempio n. 6
0
def play_game(computer: Computer, bounds: Tuple[int, int], render_speed: Optional[int] = None,
              max_screen_size: Tuple[int, int] = (1920, 1080)) \
        -> Tuple[Dict[Tuple[int, int], int], int]:
    """
    Plays the game.

    @param computer: The Intcode computer to run
    @param bounds: The bounds of the playing field
    @param render_speed: How quickly to render the game.
        render_speed == None  ::  Do not render at all
        render_speed == 0     ::  Render frame by frame, waiting for mouse clicks to advance to next frame
        render_speed == 1     ::  Render every frame
        render_speed > 1      ::  Render every n frames (n = render_speed), don't render frames in between
        render_speed < 0      ::  Render every frame, pause n milliseconds between each frame (n = -render_speed)
    @param max_screen_size: Tuple of the maximum width and height of the render screen.  Guarantees that at
    either the width or the height will exactly match its corresponding maximum, and the other dimension will
    be less than or equal to its corresponding maximum
    """

    screen, scale = build_game_screen(bounds, max_width=max_screen_size[0], max_height=max_screen_size[1]) \
        if render_speed is not None else (None, 1)

    # Set a function to call whenever input is required to give joystick inputs
    computer.input_method = ai

    screen_info = dict()
    score = 0
    initial_render_complete = False
    steps = 0
    while True:
        steps += 1
        # Get set of outputs
        outputs = computer.run_until_outputs(3)
        # If program halted, quit
        if outputs is None:
            break

        # Check if this is a score output
        if outputs[0] == -1 and outputs[1] == 0:
            score = outputs[2]
            print(score)
        else:
            # Otherwise treat it as rendering output
            screen_info[(outputs[0], outputs[1])] = outputs[2]

            # When the last wall square is done, the entire initial grid has been rendered
            if (outputs[0], outputs[1]) == bounds:
                initial_render_complete = True
                if render_speed is not None:
                    render(screen, screen_info, None, scale, False)

            # If we're rendering to screen, wait until initial render is complete, and then follow rules set by
            # the render speed
            if render_speed is not None and initial_render_complete:
                if outputs[2] == 0:
                    render(screen,
                           screen_info, (outputs[0], outputs[1]),
                           scale,
                           pause_for_clicks=False,
                           flip=False)
                elif render_speed <= 0 or render_speed <= steps:
                    render(screen,
                           screen_info, (outputs[0], outputs[1]),
                           scale,
                           pause_for_clicks=render_speed == 0
                           and initial_render_complete)
                    steps = 0

                    # If the render speed is less than zero, pause the program for an amount of
                    # milliseconds = the absolute value of that render speed
                    if render_speed < 0:
                        time.sleep(-render_speed / 1000)
    return screen_info, score
Esempio n. 7
0
def load() -> Computer:
    with open("input/input13.txt", "r") as f:
        return Computer.from_string(f.read())
Esempio n. 8
0
def replace(computer: Computer, replacements: Dict[int, int]):
    for pos, val in replacements.items():
        computer.registers[pos] = val