Ejemplo n.º 1
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
Ejemplo n.º 2
0
def main():
    """ Main Program """
    program = icc.load_data('day_09_data.txt')

    print("Part 1: Boost keycode:")
    input_data = [1]
    print(icc.run_computer(program, input_data))

    print("\nPart 2: Distress signal co-ords:")
    input_data = [2]
    print(icc.run_computer(program, input_data))
Ejemplo n.º 3
0
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
Ejemplo n.º 4
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}")
Ejemplo n.º 5
0
def part_1():
    """ Count beam locations in first 50x50 grid """
    prog = icc.load_data('day_19_data.txt')

    beam_count = 0
    for y in range(0, 50):
        for x in range(0, 50):

            beam = get_beam(x, y, prog)
            beam_count += beam

            print(f'{beam}', end='')
        print()

    print("\nPart1:")
    print(f"Beam count in first 50x50 = {beam_count}")
Ejemplo n.º 6
0
def find_max_output():
    """ Find the maximum amplifier output  for all the given phase settings

        Max Output = 262086, Max Phase Settings = (2, 1, 4, 0, 3)
    """
    program = icc.load_data("day_07_data.txt")

    max_output = 0
    max_phase = None
    for phase_settings in PHASE_VALUE_PERMUTATIONS_1:
        output = run_permutation(program, phase_settings)
        if output > max_output:
            max_output = output
            max_phase = phase_settings
        #print(f"Phase settings={phase_settings}, Output={output}")

    print('Part 1:')
    print(f"Max Output = {max_output}, Max Phase Settings = {max_phase}")
Ejemplo n.º 7
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")
Ejemplo n.º 8
0
def main():
    """ Main Program """
    # Test turn move
    coords, heading = turn_move(0, (0, 0), 0)
    coords, heading = turn_move(0, coords, heading)
    coords, heading = turn_move(0, coords, heading)
    coords, heading = turn_move(0, coords, heading)
    coords, heading = turn_move(1, coords, heading)
    coords, heading = turn_move(1, coords, heading)
    coords, heading = turn_move(1, coords, heading)
    assert turn_move(1, coords, heading) == ((0, 0), 0)

    filename = 'day_11_data.txt'
    program = icc.load_data(filename)
    painted = paint_sign(program)

    print(f'Part1: Number of painted squares = {len(painted)}')
    print(f'\nPart 2: Registration Number\n')
    print_sign(painted)
Ejemplo n.º 9
0
def part_2():
    """ Find closest distance for a 100x100 object to be fully inside the beam """
    prog = icc.load_data('day_19_data.txt')
    last_edge = 0

    for y in range(100, 5000):
        beam_edge = find_beam_edge(y, prog, last_edge)

        if beam_edge:
            last_edge = beam_edge
            # Check if the top left is inside the beam
            if check_top_right(beam_edge, y, prog):
                print(
                    "\nPart 2: Top Left corner of 100x100 box contained by beam: "
                )
                print(beam_edge, y - (BOX_SIZE - 1))
                print((beam_edge * 10000) + y - (BOX_SIZE - 1))
                sys.exit()
    print("All done")
Ejemplo n.º 10
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