Example #1
0
def find_square(data, square):
    shift = square - 1
    r = shift
    c = 0
    while True:
        while process_instructions(data[:], [c, r])[0] == 0:
            c += 1
        if process_instructions(data[:], [c + shift, r - shift])[0] == 1:
            return c, r - shift
        r += 1
Example #2
0
def process_computer_communication(data, computer_num, special_address):
    computers = [
        process_instructions(data[:], [i, -1]) for i in range(computer_num)
    ]
    special_packet = None
    last_sent_special_packet = None

    while True:
        is_packet_sent = False
        for computer in computers:
            output = next(computer)
            if output is not None:
                is_packet_sent = True
                address, x, y = output
                if address == special_address:
                    special_packet = [x, y]
                    continue
                computers[address].send([x, y])

        if not is_packet_sent and special_packet:
            computers[0].send(special_packet)
            if last_sent_special_packet and last_sent_special_packet[
                    1] == special_packet[1]:
                return special_packet[1]
            last_sent_special_packet = special_packet
            special_packet = None
Example #3
0
def play_game(data, free_game_mode, tiles):
    game_grid = start_game(data[:])
    paddle_col = find_paddle_col_pos(game_grid, tiles)
    score = 0

    def get_paddle_shift(col_pos):
        if col_pos < paddle_col:
            return -1
        if col_pos > paddle_col:
            return 1
        return 0

    data[0] = free_game_mode
    gen = process_instructions(data[:], [])
    output = next(gen)

    while True:
        try:
            col, row, tile = output
            paddle_shift = None
            if (col, row) == tiles['score']:
                score = tile
            elif tile == tiles['paddle']:
                paddle_col = col
            elif tile == tiles['ball']:
                paddle_shift = get_paddle_shift(col)
                paddle_col += paddle_shift
            output = gen.send(paddle_shift)
        except StopIteration:
            break

    return score
Example #4
0
def count_tractor_beam_points(data, square):
    count = 0
    for row in range(square):
        for col in range(square):
            if process_instructions(data[:], [row, col])[0] == 1:
                count += 1
    return count
Example #5
0
def get_scaffold_grid(data):
    gen = process_instructions(data, [])
    grid = []
    grid_row = []

    while True:
        while (output := next(gen)) != 10:
            grid_row.append(output)
        if not len(grid_row) and output == 10:
            break
        grid.append(grid_row)
        grid_row = []
Example #6
0
def process_computer_communication(data, computer_num, special_address):
    computers = [
        process_instructions(data[:], [i, -1]) for i in range(computer_num)
    ]
    while True:
        for computer in computers:
            output = next(computer)
            if output is not None:
                address, x, y = output
                if address == special_address:
                    return y
                computers[address].send([x, y])
Example #7
0
def count_dust(data, tiles, max_func_len, functions_names):
    grid = []
    gen = process_instructions(data, [])

    grid_row = ''
    while True:
        while (output := next(gen)) != 10:
            grid_row += chr(output)
        if not grid_row and output == 10:
            break
        grid.append(grid_row)
        print(grid_row)
        grid_row = ''
Example #8
0
def get_hull_damage(data):
    start_message = ''
    end_message = ''
    instructions = """OR A J
    AND B J
    AND C J
    NOT J J
    AND D J
    WALK
    """

    gen = process_instructions(data, [])

    while (output := next(gen)) != 10:
        start_message += chr(output)
Example #9
0
def get_graph(data, map_dict):
    # north, back: south; south, back: north; west, back: east; east, back: west
    moves = (((-1, 0), 2), ((1, 0), 1), ((0, -1), 4), ((0, 1), 3))
    area_map = {(0, 0): map_dict['droid']}
    gen = process_instructions(data, [])
    # initialize generator
    next(gen)

    def traverse(position, back):
        for direction, move_item in enumerate(moves, 1):
            move, new_back = move_item
            new_position = (position[0] + move[0], position[1] + move[1])
            if new_position not in area_map:
                status_code = gen.send(direction)
                area_map[new_position] = status_code
                if status_code != map_dict['wall']:
                    traverse(new_position, new_back)
        gen.send(back)

    for i in range(len(moves)):
        traverse((0, 0), moves[i][1])

    return area_map
Example #10
0
def start_game(data):
    gen = process_instructions(data, [])
    return [output for output in gen]
Example #11
0
def get_game_grid(data):
    gen = process_instructions(data, [])
    return [output for output in gen]
Example #12
0
from intcode import process_instructions


def get_game_grid(data):
    gen = process_instructions(data, [])
    return [output for output in gen]


def count_block_tiles(grid, tiles):
    block_tiles = set()
    for cell in grid:
        if cell[2] == tiles['block']:
            block_tiles.add(tuple(cell))
    return len(block_tiles)


if __name__ == "__main__":
    with open('day13/input.txt') as inp:
        ns = list(map(int, inp.read().strip().split(',')))

    game_grid = process_instructions(ns, [])
    print(count_block_tiles(game_grid, {'empty': 0, 'wall': 1, 'block': 2, 'paddle': 3, 'ball': 4}))  # 277
Example #13
0
def find_password(data):
    # cannot deal with infinite loop at runtime
    dangerous_items = ['infinite loop']
    backs = {
        'north': 'south',
        'south': 'north',
        'east': 'west',
        'west': 'east'
    }

    def traverse(direction, back):
        message = ''.join(
            list(map(chr, gen.send(list(map(ord, f'{direction[1]}\n'))))))
        print(message)
        new_directions, new_items, current_place = parse_message(message)

        if current_place is None:
            bad_item = items.pop()
            dangerous_items.append(bad_item)
            raise Exception('Bad item.')

        if current_place not in graph:
            graph[current_place] = direction

        if len(new_items):
            for new_item in new_items:
                if new_item not in dangerous_items:
                    response = gen.send(list(map(ord, f'take {new_item}\n')))
                    if isinstance(response, tuple) and response[1] is None:
                        print(''.join(list(map(chr, response[0]))))
                        dangerous_items.append(new_item)
                        return
                    print(''.join(list(map(chr, response))))
                    items.append(new_item)

        for new_direction in new_directions:
            if new_direction != back and (current_place,
                                          new_direction) not in visited:
                visited.add((current_place, new_direction))
                traverse((current_place, new_direction), backs[new_direction])
        print(''.join(list(map(chr, gen.send(list(map(ord, f'{back}\n')))))))

    # go around all the rooms and collect all the items
    # if item is dangerous, put it into dangerous_items for future reference and start again
    while True:
        try:
            items = []
            graph = {}
            visited = set()
            gen = process_instructions(data, [])
            message = ''.join(list(map(chr, next(gen))))
            print(message)
            directions, _, place = parse_message(message)
            if place:
                visited.add(place)

            for direction in directions:
                visited.add((place, direction))
                traverse((place, direction), backs[direction])
        except Exception:
            pass
        else:
            break

    # after collecting the items we're back at the beginning
    # we need to get to Pressure-Sensitive Floor room
    path = []
    place = '== Pressure-Sensitive Floor =='
    while place != '== Hull Breach ==':
        place = graph[place]
        path.append(place[1])
        place = place[0]

    path = path[::-1]
    for direction in path:
        print(''.join(
            list(map(chr, gen.send(list(map(ord, f'{direction}\n')))))))

    # we're in Pressure-Sensitive Floor room and randomly trying combinations of items
    removed_items = []
    hold_items = items[:]

    while True:
        response = gen.send(list(map(ord, f'{path[-1]}\n')))
        if isinstance(response, tuple) and response[1] is None:
            # the password is in this message
            print(''.join(list(map(chr, response[0]))))
            break
        else:
            message = ''.join(list(map(chr, response)))
            print(message)

        if 'heavier' in message:
            item = random.choice(removed_items)
            removed_items.remove(item)
            hold_items.append(item)
            print(''.join(
                list(map(chr, gen.send(list(map(ord, f'take {item}\n')))))))
        elif 'lighter' in message:
            item = random.choice(hold_items)
            hold_items.remove(item)
            removed_items.append(item)
            print(''.join(
                list(map(chr, gen.send(list(map(ord, f'drop {item}\n')))))))