Example #1
0
def main():
    program = Intcode()
    program.load_from_file('inputs/day_05_input.txt')
    program.input(5)
    program.execute()
    diagnostic_code = program.output()
    print("\nDiagnostic code is: {0}\n".format(diagnostic_code))
    return diagnostic_code
Example #2
0
def main():
    program = Intcode()
    program.load_from_file('inputs/day_09_input.txt')
    program.input(2)
    program.execute()
    while program.output_buffer:
        coordinates = program.output()
    print("\nDistress signal coordinates are: {0}\n".format(coordinates))
    return coordinates
Example #3
0
def main():
    program = Intcode()
    program.load_from_file('inputs/day_09_input.txt')
    program.input(1)
    program.execute()
    while program.output_buffer:
        key_code = program.output()
    print("\nBOOST key code is: {0}\n".format(key_code))
    return key_code
Example #4
0
def main():
    program = Intcode()
    program.load_from_file('inputs/day_02_input.txt')
    program.dsky(12, 2)
    program.execute()
    print("\nFinal value at position 0: {0}\n".format(program.memory[0]))
    return program.memory[0]
Example #5
0
def main():
    output = 19690720
    program = Intcode()
    program.load_from_file('inputs/day_02_input.txt')
    for noun, verb in \
            [(noun, verb) for noun in range(0, 100) for verb in range(0, 100)]:
        program.rewind()
        program.dsky(noun, verb)
        program.execute()
        if program.memory[0] == output:
            break
    program_code = 100 * noun + verb
    print("\nThe program outputting {0} is: {1:04d} "
          "(noun {2:02d} - verb {3:02d})\n".format(program.memory[0],
                                                   program_code, noun, verb))
    return program_code
Example #6
0
def main(start=(0, 0), display=False):
    if display:
        monitor = Display()
    else:
        monitor = None
    program = Intcode()
    program.load_from_file('inputs/day_15_input.txt')
    current = start
    environment = {current: 1}
    pathspace = Graph(nodes=[current])
    current = survey_area(program, environment, pathspace, current,
                          objective=2, monitor=monitor)
    path = pathspace.a_star(start, current,
                            lambda x: (abs(x[0]-current[0]) +
                                       abs(x[1]-current[1])))
    n_moves = len(path) - 1
    print("\nMinimum number of moves: {0}\n".format(n_moves))
    return n_moves
Example #7
0
def main():
    screen = {}
    program = Intcode()
    program.load_from_file('inputs/day_13_input.txt')
    program.execute()
    while program.output_buffer:
        x = program.output()
        y = program.output()
        v = program.output()
        screen[(x, y)] = v
    n_blocks = sum(x == 2 for x in screen.values())
    print("\nThere are a total of {0} blocks\n".format(n_blocks))
    return n_blocks
Example #8
0
def main(start=(0, 0), display=False):
    if display:
        monitor = Display()
    else:
        monitor = None
    program = Intcode()
    program.load_from_file('inputs/day_15_input.txt')
    current = start
    environment = {current: 1}
    pathspace = Graph(nodes=[current])
    # Survey all compartment
    survey_area(program,
                environment,
                pathspace,
                current,
                objective=None,
                monitor=monitor)
    # Now diffuse the oxygen
    if display:
        monitor.symbol_dict = screendict
        monitor.default_pixel = 1
    minute = -1
    open_oxygen_set = \
        [next(coordinates for coordinates, value in environment.items()
              if value == 2)]  # Only oxygen generator for now
    while open_oxygen_set:
        minute = minute + 1
        for x in open_oxygen_set:
            environment[x] = 2
        if display:
            monitor.refresh(environment, legend="MINUTE {0}".format(minute))
        # Update open set with all adjacent tiles (not yet oxygenated)
        open_oxygen_set = [
            x[1] for x in pathspace.edges
            if x[0] in open_oxygen_set and environment[x[1]] == 1
        ]
    print(
        "\nOxygen will fill the compartment in: {0} minutes\n".format(minute))
    return minute
Example #9
0
def map_scaffolding():
    program = Intcode()
    program.load_from_file('inputs/day_17_input.txt')
    program.execute()
    output = program.output_buffer
    outstr = ''.join(chr(x) for x in output)
    lines = outstr.split('\n')
    lines = [line for line in lines if line]
    return lines
Example #10
0
def paint_hull(hull, coordinates):
    # Circular list with main directions in a cartesian frame (CW order)
    # Default (starting) direction is the first, to the North
    directions = deque([(0, 1), (1, 0), (0, -1), (-1, 0)])

    def turn_left():
        directions.rotate(1)

    def turn_right():
        directions.rotate(-1)

    def direction():
        return directions[0]

    program = Intcode()
    program.load_from_file('inputs/day_11_input.txt')
    while True:
        # Provide panel color as input
        try:
            program.input(hull[coordinates])
        except KeyError:
            program.input(0)  # All panels start black
        # Let's wait for the two outputs
        while (len(program.output_buffer) < 2) and not program.ishalted:
            program.step()
        if program.ishalted:
            break
        # First output is the colour
        colour = program.output()
        hull[coordinates] = colour
        # Second output is the rotation
        rotation = program.output()
        if rotation == 0:
            turn_left()
        elif rotation == 1:
            turn_right()
        else:
            raise ValueError()
        coordinates = advance(coordinates, direction())
    return hull, coordinates
Example #11
0
def main(display=False):
    program = Intcode()
    program.load_from_file('inputs/day_13_input.txt')
    program.memory[0] = 2  # Hack to play for free
    x_ball = None
    x_paddle = None
    score = 0
    joystick = 0
    monitor = Display(screendict)
    while not program.ishalted:
        while not program.iswaiting and not program.ishalted:
            program.step()
        while program.output_buffer:
            x = program.output()
            y = program.output()
            v = program.output()
            if x == -1 and y == 0:
                score = v
            else:
                if v == 3:
                    x_paddle = x
                if v == 4:
                    x_ball = x
                monitor.update({(x, y): v})
        if (x_ball is not None) and (x_paddle is not None):
            joystick = (x_ball > x_paddle) - (x_ball < x_paddle)
            program.input(joystick)
            program.step()  # Clear the waiting condition
        if display:
            monitor.show(legend='SCORE: {0}'.format(score))
    print("\nFinal score: {0}\n".format(score))
    return score
Example #12
0
def main(display=False):
    """
    We'll only use LEFT rotations, since R = LLL, so we'll recover it later.

    We'll also work with the map spread out on a single line
    In this configuration, L-R is -/+ 1 and U-D is -/+ N, (N is a line length)

    First we trace the scaffold with the strategy "keep going forward until you
    can only turn, then turn - all until you can only backtrack".
    Then we try to compress the obtained command sequence, and give the result
    to the Intcode computer to process.
    """
    # Prepare the map
    lines = map_scaffolding()
    N = len(lines[0])
    mapstr = ''.join(lines)

    # Circular list with main directions in CW order (Up Right Down Left)
    directions = deque([-N, +1, +N, -1])

    def turn_left():
        directions.rotate(+1)  # This "rotates the robot"

    def front():
        return directions[0]  # This indicates "the direction the robot faces"

    def next_tile(position, last_visited):
        """
        Returns true if the tile in front of the robot is a valid scaffold tile
        We make sure that it's not a recently visited scaffold, so we're not
        just backtracking, hence the "valid"
        """
        try:
            new_position = position + front()
            if mapstr[new_position] == '#' and new_position != last_visited:
                # Also check that we're not crossing the L or R borders
                if not (((position % N) == 0 and front() == -1) or
                        ((position % N) == N - 1 and front() == +1)):
                    return True
        except IndexError:
            pass
        return False

    # PATHFINDING & COMMAND BUILDING
    # Find the robot
    robot_pos = re.search(r'[^\.\#]', mapstr).start()
    last_visited = None
    robot_dir = {'^': -N, '>': +1, 'v': +N, '<': -1}[mapstr[robot_pos]]
    # Align reference system, since front() by default is pointing Up
    while front() != robot_dir:
        turn_left()
    # Build command sequence as a list
    commands = []
    while True:
        rotation_timeout = 0
        while not next_tile(robot_pos, last_visited) and rotation_timeout < 4:
            turn_left()
            commands.append('L')
            rotation_timeout = rotation_timeout + 1
        if rotation_timeout == 4:
            break  # We're spinning in circles, nowhere left to go...
        counter = 0
        while next_tile(robot_pos, last_visited):
            last_visited = robot_pos
            robot_pos = robot_pos + front()
            counter = counter + 1
        commands.append(str(counter))
    # Cut away last Ls while spinning in cicles and convert LLL into R
    while commands[-1] == 'L':
        commands.pop(-1)
    replace_sublist(commands, ['L', 'L', 'L'], ['R'])
    # Compress commands
    symbols = ['A', 'B', 'C']
    sequence, functions = compress(commands, symbols, maxlen=20)

    # RUNNING THE INTCODE PROGRAM
    program = Intcode()
    program.load_from_file('inputs/day_17_input.txt')
    program.memory[0] = 2  # Manual override
    video_feed = {True: 'y', False: 'n'}[display]
    # Build program input
    program_input = '{0}\n'.format(sequence)
    for s in symbols:
        program_input = program_input + '{0}\n'.format(functions[s])
    program_input = program_input + '{0}\n'.format(video_feed)
    for x in program_input:
        program.input(ord(x))
    # Run the program
    if display:
        # Live video feed
        screen_buffer = ''
        while not program.ishalted:
            program.step()
            if program.output_buffer:
                screen_buffer += chr(program.output())
                # TODO: handle values outside of chr range
            if screen_buffer[-2:] == '\n\n':
                Display.clear()
                print(screen_buffer, end='')
                screen_buffer = ''
        dust = ord(screen_buffer[-1])  # Reconstruct dust from last output
    else:
        # Output only
        program.execute()
        dust = program.output_buffer[-1]
    # Output
    print("\nFound a solution with sequence: {0}".format(sequence))
    for symbol in symbols:
        print("{0}: {1}".format(symbol, functions[symbol]))
    print("\nTotal dust collected: {0}\n".format(dust))
    return dust