Пример #1
0
def main():
    lines = get_lines()
    # lines = [
    #     '.#.',
    #     '..#',
    #     '###',
    # ]

    grid = prepare_grid(lines)
    # print('=' * 30, 'INITIAL')
    # print_grid(grid)

    cycles = 6
    for cycle in range(1, cycles + 1):
        grid = pad_grid(grid, 1)
        # print('=' * 30, 'AFTER PADDING', cycle)
        # print_grid(grid)
        grid = run_cycle(grid)
        # print('=' * 30, 'AFTER CYCLE', cycle)
        # print_grid(grid)

    active = 0
    for z_slice in grid:
        active += sum(flatten(z_slice))

    print(active)
Пример #2
0
def main():
    lines = get_lines()

    rules = {}
    messages = []

    reading_rules = True

    for line in lines:
        if not line:
            reading_rules = False
            continue
        if reading_rules:
            key, value = line.split(': ')
            key = int(key)
            value = parse_rule(value)
            rules[key] = value
        else:
            messages.append(line)

    rules[8] = parse_rule('42 | 42 8')
    rules[11] = parse_rule('42 31 | 42 11 31')

    valid42 = set(rules_run(42, rules, {}))
    valid31 = set(rules_run(31, rules, {}))

    total_valid = 0

    for message in messages:
        total_valid += check(message, valid42, valid31)

    print(total_valid)
Пример #3
0
def main():
    lines = get_lines()

    lines = [line.replace(' ', '') for line in lines]

    total = sum(calculate_expression(line) for line in lines)
    print(total)
Пример #4
0
def main():
    lines = get_lines()

    tiles = read_tiles(lines)

    tiles = tiles_variations(tiles)

    adjacencies = {}

    for id1, tile1_variations in tiles.items():
        t1_adjacencies = adjacencies.setdefault(id1, [])
        for id2, tile2_variations in tiles.items():
            t2_adjacencies = adjacencies.setdefault(id2, [])
            if id1 != id2:
                for tile1 in tile1_variations:
                    for tile2 in tile2_variations:
                        adjacency = are_adjacent(tile1, tile2)
                        if adjacency:
                            dir1, dir2 = adjacency
                            if not in_with_key(t1_adjacencies,
                                               id2,
                                               key=lambda tup: tup[1]):
                                t1_adjacencies.append((dir1, id2, tile1))
                            if not in_with_key(t2_adjacencies,
                                               id1,
                                               key=lambda tup: tup[1]):
                                t2_adjacencies.append((dir2, id1, tile2))

    for tile_id, variations in adjacencies.items():
        tile_variations = set('\n'.join(v[2]) for v in variations)
        if len(tile_variations) > 1:
            print(tile_id, len(tile_variations))
Пример #5
0
def find_invalid():
    lines = get_lines()
    numbers = list(map(int, lines))

    preamble = []

    invalid = None

    for num in numbers:
        if len(preamble) < 25:
            preamble.append(num)
            continue
        found = False
        if len(preamble) >= 25:
            for x in preamble:
                for y in preamble:
                    if x != y and x + y == num:
                        found = True
                        break
            if not found:
                invalid = num
                break
            preamble.pop(0)
            preamble.append(num)

    return invalid
Пример #6
0
def main():
    lines = get_lines()

    # life days -> fish count with same life days
    lantern_fish = Counter()

    for fish in (int(x) for x in lines[0].split(',')):
        lantern_fish[fish] += 1

    day = 0

    while day < 256:
        # print(day, print_dict(lantern_fish))

        min_fish = min(lantern_fish.keys()) + 1

        new_lantern_fish = Counter()

        for life, fish_count in lantern_fish.items():
            new_lantern_fish[life - min_fish] = fish_count

        day += min_fish

        lantern_fish = new_lantern_fish
        del new_lantern_fish

        lantern_fish[6] += lantern_fish[-1]
        lantern_fish[8] += lantern_fish[-1]
        lantern_fish.pop(-1)

    # print(day, print_dict(lantern_fish))
    print(sum(lantern_fish.values()))
Пример #7
0
def main():
    lines = get_lines()

    graph = read_graph(lines)
    paths = find_all_paths(graph)

    for i, path in enumerate(paths, start=1):
        print(i, path)
Пример #8
0
def main():
    lines = get_lines()

    dots, folds = read_input(lines)

    for fold in folds:
        dots = fold_matrix(dots, fold)

    print_dots(dots)
Пример #9
0
def main():
    lines = get_lines()

    dots, folds = read_input(lines)

    folded = fold_matrix(dots, folds[0])

    visible = len(folded)

    print(visible)
Пример #10
0
def main():
    lines = get_lines()

    grid = read_grid(lines)

    for step in range(10000):
        grid, flashed_count = simulate_step(grid)
        if flashed_count == 100:
            print(step + 1)
            break
Пример #11
0
def main():
    lines = get_lines()

    numbers = list(map(int, lines))
    increases = 0

    for i in range(1, len(numbers)):
        if numbers[i] > numbers[i - 1]:
            increases += 1

    print(increases)
Пример #12
0
def main():
    global games_played

    lines = get_lines()

    player1_cards, player2_cards = read_cards(lines)

    games_played += 1
    winner, winner_cards = play_game(games_played, player1_cards,
                                     player2_cards)

    print(calculate_score(winner_cards))
Пример #13
0
def main():
    lines = get_lines()

    oxygen_numbers = examine(lines[:], 'oxygen')
    co2_numbers = examine(lines[:], 'co2')

    oxygen = int(oxygen_numbers[0], base=2)
    co2 = int(co2_numbers[0], base=2)

    life_support_rating = oxygen * co2

    print(life_support_rating)
Пример #14
0
def main():
    lines = get_lines()

    lines = list(map(parse_input, lines))

    total = 0

    for input, output in lines:
        unique_input = [o for o in output if len(o) in UNIQUE_LENGTHS.values()]
        total += len(unique_input)

    print(total)
Пример #15
0
def main():
    lines = get_lines()

    numbers, boards = read_input(lines)
    marker_boards = [generate_marker_board() for _ in range(len(boards))]

    for number in numbers:
        for board, marker_board in zip(boards, marker_boards):
            mark_number(number, board, marker_board)
            if is_winner(marker_board):
                total = count_board(board, marker_board)
                print(total * number)
                return
Пример #16
0
def main():
    lines = get_lines()
    cups = list(map(int, lines[0]))

    current = cups[0]

    for move in range(1, 101):
        cups, removed = remove_cups(cups, current)
        destination = find_destination(cups, current)
        cups = add_cups(cups, removed, destination)
        current = find_new_current(cups, current)

    after_1 = after_cup(cups, 1)
    print(''.join(map(str, after_1)))
Пример #17
0
def main():
    lines = get_lines()

    heightmap = [[int(c) for c in line] for line in lines]

    basins = []

    for row_idx, row in enumerate(heightmap):
        for col_idx, col in enumerate(row):
            adjacent_list = adjacent(heightmap, row_idx, col_idx)
            if col < min(value for position, value in adjacent_list):
                basin = find_basin(heightmap, row_idx, col_idx)
                basins.append(len(basin))

    print(reduce(lambda a, b: a * b, sorted(basins, reverse=True)[:3], 1))
Пример #18
0
def main():
    lines = get_lines()

    heightmap = [[int(c) for c in line] for line in lines]

    total = 0

    for row_idx, row in enumerate(heightmap):
        for col_idx, col in enumerate(row):
            adjacent_values = adjacent(heightmap, row_idx, col_idx)
            if col < min(adjacent_values):
                # print(row_idx, col_idx, col)
                total += col + 1

    print(total)
Пример #19
0
def main():
    lines = get_lines()

    numbers = list(map(int, lines))
    increases = 0
    last3 = [*numbers[:3]]

    for i in range(3, len(numbers)):
        sum_prev = sum(last3)
        last3.pop(0)
        last3.append(numbers[i])
        sum_next = sum(last3)
        if sum_next > sum_prev:
            increases += 1

    print(increases)
Пример #20
0
def main():
    lines = get_lines()

    horizontal_position = 0
    depth = 0

    for command in lines:
        direction, amount = parse_command(command)
        if direction == 'forward':
            horizontal_position += amount
        elif direction == 'down':
            depth += amount
        elif direction == 'up':
            depth -= amount

    print(horizontal_position * depth)
Пример #21
0
def main():
    lines = get_lines()

    transposed = transpose(lines)
    gamma = ''

    for item in transposed:
        data = Counter(item)
        gamma += data.most_common(1)[0][0]

    bits_count = len(gamma)
    gamma = int(gamma, base=2)
    epsilon = bit_not(gamma, bits_count)

    power_consumption = gamma * epsilon

    print(power_consumption)
Пример #22
0
def main():
    lines = get_lines()

    lantern_fish = [int(x) for x in lines[0].split(',')]

    for day in range(80):
        # print(day, lantern_fish)
        fish_to_add = 0
        for fish_idx in range(len(lantern_fish)):
            lantern_fish[fish_idx] -= 1
            if lantern_fish[fish_idx] < 0:
                lantern_fish[fish_idx] = 6
                fish_to_add += 1
        for idx in range(fish_to_add):
            lantern_fish.append(8)

    print(len(lantern_fish))
Пример #23
0
def main():
    lines = get_lines()

    recipes = [parse_recipe(line) for line in lines]

    allergens_recipes = {}
    ingredients_allergens_recipes = {}

    for ingredients, allergens in recipes:
        for allergen in allergens:
            allergens_recipes.setdefault(allergen, 0)
            allergens_recipes[allergen] += 1
        for ingredient in ingredients:
            ingredient_allergens = ingredients_allergens_recipes.setdefault(ingredient, {})
            for allergen in allergens:
                ingredient_allergens.setdefault(allergen, 0)
                ingredient_allergens[allergen] += 1

    marked_ingredients = set()

    for allergen, allergen_count in allergens_recipes.items():
        ingredients = [ingredient for ingredient, ingredient_allergens in ingredients_allergens_recipes.items() if (allergen, allergen_count) in ingredient_allergens.items()]
        marked_ingredients.update(ingredients)

    marked_ingredients = list(marked_ingredients)
    marked_ingredients_idx = 0

    figured_ingredients = {}

    while marked_ingredients:
        marked_ingredients_idx %= len(marked_ingredients)
        ingredient = marked_ingredients[marked_ingredients_idx]
        temp = [(allergen, recipes_count) for allergen, recipes_count in ingredients_allergens_recipes[ingredient].items() if (allergen, recipes_count) in allergens_recipes.items() and allergen not in figured_ingredients.values()]
        if len(temp) == 1:
            figured_ingredients[ingredient] = temp[0][0]
            marked_ingredients.remove(ingredient)
        else:
            temp_max = [(allergen, recipes_count) for allergen, recipes_count in temp if (allergen, recipes_count) in allergens_recipes.items() and allergen not in figured_ingredients.values()]
            if len(temp_max) == 1:
                figured_ingredients[ingredient] = temp[0][0]
                marked_ingredients.remove(ingredient)
        marked_ingredients_idx += 1

    result = [ingredient for ingredient, allergen in sorted(figured_ingredients.items(), key=lambda tup: tup[1])]
    print(','.join(result))
Пример #24
0
def main():
    lines = get_lines()

    numbers, boards = read_input(lines)
    marker_boards = [generate_marker_board() for _ in range(len(boards))]

    winning_log = []

    for number in numbers:
        for board, marker_board in zip(boards, marker_boards):
            if is_winner(marker_board):
                continue
            mark_number(number, board, marker_board)
            if is_winner(marker_board):
                total = count_board(board, marker_board)
                winning_log.append(total * number)

    print(winning_log[-1])
Пример #25
0
def main():
    lines = get_lines()

    errors = {bracket: 0 for bracket in BRACKET_END}

    for line in lines:
        stack = []
        for bracket in line:
            if bracket in BRACKET_START:
                stack.append(bracket)
            else:
                last = stack.pop()
                if not are_match(last, bracket):
                    errors[bracket] += 1

    total = sum(ERROR_POINTS[bracket] * count
                for bracket, count in errors.items())

    print(total)
Пример #26
0
def main():
    lines = get_lines()

    lines = [read_line(line) for line in lines]
    # lines = list(filter(lambda line: line.x1 == line.x2 or line.y1 == line.y2, lines))

    board = generate_board(lines)

    for line in lines:
        mark_board(board, line)

    total = 0

    for row in board:
        for col in row:
            if col >= 2:
                total += 1

    print(total)
Пример #27
0
def main():
    lines = get_lines()

    template, pairs = read_input(lines)

    for step in range(10):
        new_template = []
        for idx in range(1, len(template)):
            s1, s2 = template[idx - 1], template[idx]
            window = s1 + s2
            if len(new_template) == 0:
                new_template.append(s1)
            new_template.append(f'{pairs[window]}{s2}')
        template = ''.join(new_template)

    counter = Counter(template)
    common = counter.most_common()
    most_common, least_common = common[0], common[-1]
    print(most_common[1] - least_common[1])
Пример #28
0
def main():
    lines = get_lines()

    lines = list(map(parse_input, lines))

    total = 0

    for input, output in lines:
        unique_input = [i for i in input if len(i) in UNIQUE_LENGTHS.values()]

        one = find_by_number(unique_input, 1)
        four = find_by_number(unique_input, 4)
        seven = find_by_number(unique_input, 7)
        eight = find_by_number(unique_input, 8)

        unique_segments = deduct_unique_segments(one, four, seven, eight)

        two_three_five = find_by_length(input, 5)
        zero_six_nine = find_by_length(input, 6)

        other_numbers = deduct_other_numbers(unique_segments, two_three_five,
                                             zero_six_nine)

        all_numbers = other_numbers.copy()
        all_numbers[1] = one
        all_numbers[4] = four
        all_numbers[7] = seven
        all_numbers[8] = eight

        output_number = ''

        for num in output:
            for digit, string_num in all_numbers.items():
                if is_same_number(num, string_num):
                    output_number += str(digit)
                    break

        total += int(output_number)

    print(total)
Пример #29
0
def main():
    lines = get_lines()

    recipes = [parse_recipe(line) for line in lines]

    allergens_recipes = {}
    ingredients_allergens_recipes = {}

    for ingredients, allergens in recipes:
        for allergen in allergens:
            allergens_recipes.setdefault(allergen, 0)
            allergens_recipes[allergen] += 1
        for ingredient in ingredients:
            ingredient_allergens = ingredients_allergens_recipes.setdefault(
                ingredient, {})
            for allergen in allergens:
                ingredient_allergens.setdefault(allergen, 0)
                ingredient_allergens[allergen] += 1

    marked_ingredients = set()

    for allergen, allergen_count in allergens_recipes.items():
        ingredients = [
            ingredient for ingredient, ingredient_allergens in
            ingredients_allergens_recipes.items()
            if (allergen, allergen_count) in ingredient_allergens.items()
        ]
        marked_ingredients.update(ingredients)

    safe_ingredients = ingredients_allergens_recipes.keys(
    ) - marked_ingredients

    recipes_with_safe_ingredients = 0

    for ingredients, allergens in recipes:
        recipes_with_safe_ingredients += sum(ing in ingredients
                                             for ing in safe_ingredients)

    print(recipes_with_safe_ingredients)
Пример #30
0
def main():
    lines = get_lines()

    tiles = read_tiles(lines)

    tiles = tiles_variations(tiles)

    adjacencies = {}

    for id1, tile1_variations in tiles.items():
        t1_adjacencies = adjacencies.setdefault(id1, set())
        for id2, tile2_variations in tiles.items():
            t2_adjacencies = adjacencies.setdefault(id2, set())
            if id1 != id2:
                for tile1 in tile1_variations:
                    for tile2 in tile2_variations:
                        adjacency = are_adjacent(tile1, tile2)
                        if adjacency:
                            dir1, dir2 = adjacency
                            t1_adjacencies.add((dir1, id2))
                            t2_adjacencies.add((dir2, id1))

    corners = []

    for tile_id, variations in adjacencies.items():
        unique_variations = unique(variations, key=lambda tup: tup[1])
        if len(unique_variations) == 2:
            corners.append(tile_id)

    if len(corners) == 4:
        print(corners)
        ids_multiplied = 1
        for tile_id in corners:
            ids_multiplied *= tile_id
        print(ids_multiplied)
    else:
        print(
            f"no 4 corners, actual count = {len(corners)}, corners = {corners}"
        )