def run_feedback_loop(phase_settings):
    """ Modify the computer to use Queues for inputs and outputs.
        Computer will block if input required and input Queue is empty.

        Will run each computer in a separate thread so they can run
        simultaneously.
    """
    program = icc.load_data("day_7_data.txt")

    thread_pool = []
    thread_pool_size = 5

    # Setup pool of amp int code computers with feedback configuration
    amp_pool = []
    amp_pool.append(icc.IntCodeComputer(program))
    amp_pool.append(icc.IntCodeComputer(program, amp_pool[0].output))
    amp_pool.append(icc.IntCodeComputer(program, amp_pool[1].output))
    amp_pool.append(icc.IntCodeComputer(program, amp_pool[2].output))
    amp_pool.append(
        icc.IntCodeComputer(program, amp_pool[3].output, amp_pool[0].input))

    # Pre-load all the pahse settings
    for i in range(thread_pool_size):
        amp_pool[i].input.put(phase_settings[i])

    # Give Amp 0 the starting input value of 0
    amp_pool[0].input.put(0)

    for i in range(thread_pool_size):
        # Setup a worker thread for each amp and insert the phase settings
        # input each of the input queues.
        worker_thread = threading.Thread(target=amp_pool[i].run_program)

        # Deamonise the threads (so the die nicely when the script ends
        # May not be needed but stops stray threads being left behind if
        # we have a crash or some other weird exit.
        worker_thread.daemon = True

        # Start each of the threads running
        worker_thread.start()

        # Add them to pool list so we can keep track of them
        thread_pool.append(worker_thread)

    # Wait here for all the threads to exit properly
    for thd in thread_pool:
        thd.join()

    return amp_pool[4].result
Exemple #2
0
 def __init__(self, int_code, address):
     self.int_code = int_code.copy()
     # The intcode needs the address as the first input value.
     self.input_stream = self.InputStream([address])
     self.output_stream = []
     self.computer = int_code_computer.IntCodeComputer(
         self.int_code, self.input_stream, self.output_stream)
Exemple #3
0
 def __init__(self, int_code: List[int], mode: Mode) -> None:
     self._input_stream: List[int] = []
     self._output_stream: List[int] = []
     my_int_code = int_code.copy()
     my_int_code[0] = mode.value
     self._computer = int_code_computer.IntCodeComputer(my_int_code, self._input_stream,
                                                        self._output_stream)
Exemple #4
0
def part2(input_list):
    int_code = parse_input(input_list[0])
    input_stream = [2]
    output_stream = []
    computer = int_code_computer.IntCodeComputer(int_code, input_stream,
                                                 output_stream)
    computer.run()
    return output_stream[-1]
Exemple #5
0
    def __init__(self, int_code):
        self._location = aoc.Coord(0, 0)
        self._input_stream = []
        self._output_stream = []

        self.icc = int_code_computer.IntCodeComputer(int_code,
                                                     self._input_stream,
                                                     self._output_stream)
Exemple #6
0
 def __init__(self, int_code, ship, start_color=0):
     self._input_stream = [start_color]
     self._output_stream = []
     self._computer = int_code_computer.IntCodeComputer(int_code, self._input_stream,
                                                        self._output_stream)
     self._direction = aoc.Coord(0, 1)
     self._location = aoc.Coord(0, 0)
     self._ship = ship
     self._paint_used = 0
def main():
    """ Main Program """
    print('Part 1:')
    program = icc.load_data('day_17_data.txt')
    comp = icc.IntCodeComputer(program)
    comp.run_program()

    maze_raw = []
    while not comp.output.empty():
        maze_raw.append(comp.output.get())

    maze = build_maze(maze_raw)
    crossings = find_crossings(maze)
    print_maze(maze)
    print(f"\nAlignment sum = {sum_alignments(crossings)}")

    print('\nPart 2:')
    program = icc.load_data('day_17_data.txt')
    program[0] = 2  # Wake up the robot
    comp = icc.IntCodeComputer(program)

    # Load the movement instructions
    for ins in build_instructions():
        comp.input.put(ins)

    # Load the y/n for video feed
    comp.input.put(ord('n'))
    comp.input.put(ord('\n'))

    comp_thread = threading.Thread(target=comp.run_program)
    comp_thread.daemon = True
    comp_thread.start()

    output = []
    while True:
        out = comp.output.get()
        output.append(out)
        try:
            print(chr(out), end='')
        except ValueError:
            print(out)
            break
Exemple #8
0
    def check_point(self, coord):
        """
        :param coord:  aoc.Coord to check.
        :return:  True if point is in tractor beam area.
        """
        input_stream = [coord.x_val, coord.y_val]
        output_stream = []
        computer = int_code_computer.IntCodeComputer(self.int_code, input_stream, output_stream)
        computer.run()

        return output_stream[0] == 1
Exemple #9
0
def simulate_amplifiers(int_code, feedback_mode):
    # pylint: disable=too-many-locals
    max_output = 0

    for phase_configuration in get_phases_permutations(feedback_mode):
        # First computer gets 0 for input.
        stream_into_a = [phase_configuration[0], 0]
        stream_into_b = [phase_configuration[1]]
        stream_into_c = [phase_configuration[2]]
        stream_into_d = [phase_configuration[3]]
        stream_into_e = [phase_configuration[4]]

        amp_a = int_code_computer.IntCodeComputer(int_code, stream_into_a,
                                                  stream_into_b)
        amp_b = int_code_computer.IntCodeComputer(int_code, stream_into_b,
                                                  stream_into_c)
        amp_c = int_code_computer.IntCodeComputer(int_code, stream_into_c,
                                                  stream_into_d)
        amp_d = int_code_computer.IntCodeComputer(int_code, stream_into_d,
                                                  stream_into_e)
        amp_e = int_code_computer.IntCodeComputer(int_code, stream_into_e,
                                                  stream_into_a)

        if feedback_mode:
            until = int_code_computer.IntCodeComputer.OUTPUT
        else:
            until = int_code_computer.IntCodeComputer.HALT

        while not amp_e.is_halted():
            amp_a.run(until=until)
            amp_b.run(until=until)
            amp_c.run(until=until)
            amp_d.run(until=until)
            amp_e.run(until=until)

        last_output = stream_into_a[0]
        if last_output > max_output:
            max_output = last_output

    return max_output
Exemple #10
0
def part2(input_list):
    """
    Run thermal radiator controller diagnostic.
    """

    int_code = parse_input(input_list[0])

    input_stream = [5]  # System ID for thermal radiator controller.
    output_stream = []
    computer = int_code_computer.IntCodeComputer(int_code, input_stream,
                                                 output_stream)
    computer.run()
    return output_stream[-1]
Exemple #11
0
def part1(input_list):
    """
    Basic test of int code computer.  Run air conditioning diagnostic.
    """

    int_code = parse_input(input_list[0])

    input_stream = [1]  # System ID for air conditioning.
    output_stream = []
    computer = int_code_computer.IntCodeComputer(int_code, input_stream,
                                                 output_stream)
    computer.run()
    return output_stream[-1]
Exemple #12
0
def part1(input_list):
    """
    Basic test of int code computer.
    """

    int_code = int_code_computer.IntCodeComputer.parse_input(input_list[0])

    int_code[1] = 12
    int_code[2] = 2

    computer = int_code_computer.IntCodeComputer(int_code)
    computer.run()
    return computer.get_memory(0)
def run_permutation(program, phase_values):
    """ Calculate the output from the amplifier bank for the
        given set of phase settings
    """
    next_input_data = 0

    for i in range(0, 5):
        computer = icc.IntCodeComputer(program,
                                       [phase_values[i], next_input_data])
        computer.run_program()
        next_input_data = computer.result[-1]

    return next_input_data
Exemple #14
0
def part_1():
    """ Part 1: Count bricks left at the end
    """

    program = icc.load_data('day_13_data.txt')
    comp = icc.IntCodeComputer(program)
    comp.run_program()

    # Build an empty grid
    grid = [['' for _ in range(24)] for _ in range(37)]

    update_grid(comp, grid)
    print_grid(grid)
    blocks_left = sum([row.count(2) for row in grid])
    print(f"Part1: Blocks left = {blocks_left}")
Exemple #15
0
    def run(self, ascii_code):
        input_stream = list(map(ord, ascii_code))
        output_stream = []
        computer = int_code_computer.IntCodeComputer(self._int_code,
                                                     input_stream,
                                                     output_stream)
        computer.run()

        if output_stream[-1] < 256:
            camera_output = "".join(map(chr, output_stream))
            damage = None
        else:
            camera_output = None
            damage = output_stream[-1]

        return camera_output, damage
Exemple #16
0
    def __init__(self, int_code):
        self._serial_number = self._next_serial_number
        self._next_serial_number += 1
        self._input_stream = []
        self._output_stream = []
        self._computer = int_code_computer.IntCodeComputer(
            int_code, self._input_stream, self._output_stream)
        self._room = ''
        self._rooms_visited = []
        self._doors = []
        self._items_here = []
        self._items_carried = set()

        self._output = ""
        self._keypad_code = None

        self._run()
Exemple #17
0
def part_2():
    """ Part 2: Play the game until no blocks left.
    """
    program = icc.load_data('day_13_data.txt')

    # 2 = Free play
    program[0] = 2

    # Start a thread here to run the computer
    comp = icc.IntCodeComputer(program)
    comp_thread = threading.Thread(target=comp.run_program)
    comp_thread.daemon = True
    comp_thread.start()

    # Build an empty grid
    grid = [['' for _ in range(24)] for _ in range(37)]

    # Run the computer and cature the next grid iteration
    # Apply an input to move the paddle for the next step.
    update_grid(comp, grid)
    last_ball_x = find_ball(grid)
    print_grid(grid)
    comp.input.put(-1)

    while not comp.halt_status:
        if not comp.output.empty():
            update_grid(comp, grid)
            print_grid(grid)
            ball_x = find_ball(grid)

            paddle_x = find_paddle(grid)
            moves = abs(paddle_x - ball_x)
            if moves != 0:
                for _ in range(moves):
                    if ball_x > last_ball_x:
                        comp.input.put(1)
                    else:
                        comp.input.put(-1)
            else:
                comp.input.put(0)

            last_ball_x = ball_x

    print("GAME OVER")
Exemple #18
0
def paint_sign(program):
    """ Run the intCode computer with the given painting program
        Give 0 as initial input then paint, move and give next input.
        Next imput is the colour we have painted the square or if
        not painted then we return black by default.

        0 = Black
        1 = White

    """
    # Dict with keys of tuples for painted squares
    # Values = colour of paint
    # {(x1,y1): c1, (x2, y2):c2  ...}
    initial_colour = 1
    painted = {(0, 0): 1}

    # Start a thread here to run the computer
    comp = icc.IntCodeComputer(program, [initial_colour])
    comp_thread = threading.Thread(target=comp.run_program)
    comp_thread.daemon = True
    comp_thread.start()

    # Setup initial position
    coords = (0, 0)
    heading = 0

    while not comp.halt_status:
        # Get paint colour
        paint_colour = comp.output.get()
        turn_direction = comp.output.get()
        #print(f"Paint= {paint_colour}, Turn= {turn_direction}")

        # Paint the square (overwrites any existing paint in the square)
        painted[coords] = paint_colour

        # Execute instructed move
        coords, heading = turn_move(turn_direction, coords, heading)

        # Get input for new square
        inp = painted.get(coords, 0)
        comp.input.put(inp)

    return painted
Exemple #19
0
def part2(input_list):
    """
    Find int code noun and verb that produces the desired output.
    """

    desired_output = 19690720

    noun = None  #for PyLint
    verb = None  #for PyLint
    for noun, verb in itertools.product(range(100), range(100)):
        int_code = int_code_computer.IntCodeComputer.parse_input(input_list[0])

        int_code[1] = noun
        int_code[2] = verb

        computer = int_code_computer.IntCodeComputer(int_code)
        computer.run()
        result = computer.get_memory(0)
        if result == desired_output:
            break

    return noun * 100 + verb
Exemple #20
0
def build_maze():
    # pylint: disable=too-many-branches
    """ Run the maze and print out the walls
    """

    program = icc.load_data("day_15.txt")

    # Start a thread here to run the computer
    comp = icc.IntCodeComputer(program)
    comp_thread = threading.Thread(target=comp.run_program)
    comp_thread.daemon = True
    comp_thread.start()

    maze = {}
    d_posn = INITIAL_POSN
    direction = 1
    s_found = False
    all_done = False

    # Make the first move
    comp.input.put(direction)
    while not comp.waiting:
        time.sleep(0.1)

    while not all_done:

        while not comp.output.empty():
            out = comp.output.get()
            d_posn = update_maze(maze, direction, out, d_posn)

            # Keep left hand on the wall
            if out == 0:
                if direction == 1:
                    direction = 4
                elif direction == 2:
                    direction = 3
                elif direction == 3:
                    direction = 1
                elif direction == 4:
                    direction = 2
            elif out == 1:
                if direction == 1:
                    direction = 3
                elif direction == 2:
                    direction = 4
                elif direction == 3:
                    direction = 2
                elif direction == 4:
                    direction = 1
            elif out == 2:
                s_found = True

            comp.input.put(direction)

        if s_found is True and d_posn == INITIAL_POSN:
            all_done = True

    print_maze(maze, d_posn)
    #min_x = min([x[0] for x in maze])
    #max_x = max([x[0] for x in maze])

    #min_y = min([x[1] for x in maze])
    #max_y = max([x[1] for x in maze])

    #print(min_x, min_y)
    #print(max_x, max_y)

    return maze
Exemple #21
0
def get_beam(x, y, prog):
    """ Get the beam value at the given co-ords """
    input_data = [x, y]
    comp = icc.IntCodeComputer(prog, input_data)
    comp.run_program()
    return comp.output.get()