Пример #1
0
def main(parttwo=False):
    inp = aoc_utils.input_block_list()
    count = 0
    for group in inp:
        if parttwo:
            splitgroup = aoc_utils.filter_empty(group.split("\n"))
            li1 = set(splitgroup[0])
            for line in splitgroup[1:]:
                li1 = li1.intersection(set(line))
            count += len(li1)
        else:
            group = group.replace("\n", "")
            count += len(set(group))
    return count
Пример #2
0
def main(parttwo=False):
    passports = aoc_utils.input_block_list()
    valid = 0
    for passport in passports:
        passport = passport.replace("\n", " ")
        if not all(passport.count(field) == 1 for field in fields):
            continue
        # this RegEx is *so* close and yet I'm still getting an off-by-one error somewhere
        # it outputs 138 when it should be 137 but not exactly sure why
        if (
            parttwo
            and re.match(
                r"(?=.*byr:(19[2-9][0-9]|200[1-2]))(?=.*iyr:(201[0-9]|2020))(?=.*eyr:(202[0-9]|2030))(?=.*hgt:(1[5-8][0-9]cm|19[0-3]cm|59in|6[0-9]in|7[0-6]in))(?=.*hcl:#(?:[0-9a-fA-F]{3}){1,2})(?=.*ecl:(amb|blu|brn|gry|grn|hzl|oth))(?=.*pid:\d{9})",
                passport,
            )
            is None
        ):
            continue
        if parttwo:
            print(passport)
        valid += 1
    return valid
Пример #3
0
    return list(map(lambda x: list(map(int, x.split())), board.split("\n")))


def filter_minus_ones_from_board(board: list[list[int]]) -> list[list[int]]:
    return list(map(lambda row: list(filter(lambda x: x != -1, row)), board))


def min_drawn_numbers_for_board(
    numbers: list[int], board: list[list[int]]
) -> tuple[bool, int, int]:
    index = 0
    while all(sum(row) > -5 for row in board) and all(
        sum(col) > -5 for col in zip(*board)
    ):
        for row in board:
            if numbers[index] in row:
                row[row.index(numbers[index])] = -1
        index += 1
    if [-1, -1, -1, -1, -1] in board:
        return False, board.index([-1, -1, -1, -1, -1]), index
    for i, column in enumerate(zip(*board)):
        if sum(column) == -5:
            return True, i, index


if __name__ == "__main__":
    numbers_up, *boards_up = aoc_utils.input_block_list()
    numbers = list(map(int, numbers_up.strip().split(",")))
    boards = list(map(parse_board, boards_up))
    main(numbers, boards)
Пример #4
0
            if pair not in rules:
                continue

            # we cannot reset to zero here, as this pair may have been
            # or will be affected by other substitutions in this iteration
            pairs[pair] -= count

            # add appropriately to the two new element-pairs formed
            pairs[pair[0] + rules[pair]] += count
            pairs[rules[pair] + pair[1]] += count

    # admittedly Counter is somewhat ott here, could have used
    # defaultdict or any other of the myriad of solutions
    c = Counter()
    for elements, count in pairs.items():
        for element in elements:
            c[element] += count

    # adjust for first and last elements which are never changed
    # these are not double counted so we add one to double count them
    c[molecule[0]] += 1
    c[molecule[-1]] += 1

    cmc = c.most_common()
    print(cmc[0][1] // 2 - cmc[-1][1] // 2)


if __name__ == "__main__":
    main2(*aoc_utils.input_block_list(), 10)
    main2(*aoc_utils.input_block_list(), 40)
Пример #5
0
    return int(scanner_no[0]), data


def gen_deltas(vectors: list[tuple[int, int, int]]):
    """
    for every possible pair of position vectors, calculate the vector between the two.
    NB: for points A, B both A --> B and B --> A are generated; n * (n - 1) items returned
    returned in format (delta, (v_start, v_end))
    """
    yield from ((vector_delta(triple1, triple2), (triple1, triple2))
                for triple1, triple2 in itertools.permutations(vectors, 2)
                if triple1 != triple2)


if __name__ == "__main__":
    data = dict(map(parse_scanner, aoc_utils.input_block_list()))

    q = queue.Queue()
    beacons = set()
    fixed_scanners = {0: 0}
    scanner_locations = {0: (0, 0, 0)}
    q.put(0)

    while not q.empty():
        fixed_scanner_no = q.get()

        fixed_deltas = dict(
            gen_deltas(
                map(
                    orientations[fixed_scanners[fixed_scanner_no]],
                    data[fixed_scanner_no],
Пример #6
0
    # dir is one of x or y
    # number is the coordinate line along which to fold
    for dir, num in folds:
        to_remove = set()
        new_coords = set()
        for px, py in coords:
            if dir == "x" and px > num:
                to_remove.add((px, py))
                new_coords.add((num - abs(px - num), py))
            elif dir == "y" and py > num:
                to_remove.add((px, py))
                new_coords.add((px, num - abs(py - num)))
        coords -= to_remove
        coords |= new_coords
        if not printed:
            print(f"Part 1: {len(coords)} points after first fold")
            printed = True
    
    print("#### Part 2: Decipher the 8 characters below")
    for y in range(max(c[1] for c in coords) + 1):
        for x in range(max(c[0] for c in coords) + 1):
            if (x, y) in coords:
                print("#", end="")
            else:
                print(" ", end="")
        print()


if __name__ == "__main__":
    main(*aoc_utils.input_block_list())
Пример #7
0
                lambda acc, neighbour: (acc * 2)
                | int(neighbour in lit_pixels)
                | (infinite_lit and
                   (neighbour[0] < min_x or neighbour[0] > max_x or neighbour[
                       1] < min_y or neighbour[1] > max_y)),
                gen_adjacent_coords((x, y)),
                0,
            )
            new_value = algorithm[index]
            if new_value == 1:
                new_lit_pixels.add((x, y))
    return new_lit_pixels, not infinite_lit


if __name__ == "__main__":
    algorithm_str, image_str = aoc_utils.input_block_list()

    algorithm = dict((i, int(v == "#")) for i, v in enumerate(algorithm_str))

    lit_pixels = set()
    for y, row in enumerate(image_str.splitlines()):
        for x, value in enumerate(row):
            if value == "#":
                lit_pixels.add((x, y))

    infinite_lit = False
    for _ in range(2):
        lit_pixels, infinite_lit = main(algorithm, lit_pixels, infinite_lit)

    print(len(lit_pixels))