Exemplo n.º 1
0
    resulting_molecules = set()
    for mol_from, mol_to in replacements:
        for index in [m.start() for m in re.finditer(mol_from, molecule)]:
            new_molecule = molecule[:index] + molecule[index:].replace(
                mol_from, mol_to, 1)
            resulting_molecules.add(new_molecule)
    return resulting_molecules


example_molecule = "HOH"
example_replacements = (("H", "HO"), ("H", "OH"), ("O", "HH"), ("e", "H"),
                        ("e", "O"))

print(find_all_resulting_molecules(example_molecule, example_replacements))

u.answer_part_1(len(find_all_resulting_molecules(molecule, replacements)))

#
#                         _\/_
#                          /\
#                          /\
#                         /  \
#                         /~~\o
#       PART    ------   /o   \  ------  TWO
#                       /~~*~~~\
#                      o/    o \
#                      /~~~~~~~~\~`
#                     /__*_______\
#                          ||
#                        \====/
#                         \__/
Exemplo n.º 2
0
# class CaloriesVector(NamedTuple):
# a: int
# b: str
# c: dict
# def __mul__(self, other):
# pass

# from operator import attrgetter
# persons.sort()
# sorted(persons, key=attrgetter('info.age')) # plus performant que la version lambda
# sorted(persons, key=attrgetter('info.age', 'info.taille')) # ha ! va écrire une lambda équivalente
# sorted(persons, key=lambda x: x.info.age)

size = 100  # 156 849 iterations for size 100
generator = ((x, y, z, size - x - y - z) for x in range(1, size)
             for y in range(1, size - x) for z in range(1, size - x - y))
maxScore = 0
maxScores500Calories = 0
for row in generator:
    score = math.prod(
        [max(0, dot(constraint, row)) for constraint in constraints])
    calories = dot(row, caloriesVector)
    if score > maxScore:
        maxScore = score
    if calories == 500 and score > maxScores500Calories:
        maxScores500Calories = score
    # print(f'\033[91m'+'a'*row[0]+'\033[92m'+'b'*row[1]+'\033[94m'+'c'*row[2]+'\033[93m'+'d'*row[3]+f'\033[0m {score}')

u.answer_part_1(maxScore)
u.answer_part_2(maxScores500Calories)
Exemplo n.º 3
0
SUBJECT = 7

# part 1 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def find_loop_size(public_key: int):
    value = 1
    for loop_size in itertools.count(start=1):
        value = (value * SUBJECT) % MODULO
        if value == public_key:
            return loop_size


def find_encryption_key(public_key: int, loop_size_of_other_device: int):
    return pow(public_key, loop_size_of_other_device, MODULO)


u.assert_equals(find_loop_size(5764801), 8)
u.assert_equals(find_loop_size(17807724), 11)

u.assert_equals(find_encryption_key(5764801, 11), 14897079)

card_loop_size = find_loop_size(card_key)
u.pink(f"card loop: {card_loop_size}")
encryption_key = find_encryption_key(door_key, card_loop_size)

u.answer_part_1(encryption_key)
# 1018011 too low

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_
Exemplo n.º 4
0
            return False
    return True


criteria = {
    "children": 3,
    "cats": 7,
    "samoyeds": 2,
    "pomeranians": 3,
    "akitas": 0,
    "vizslas": 0,
    "goldfish": 5,
    "trees": 3,
    "cars": 2,
    "perfumes": 1,
}
parser = r"""Sue\s(\d+)\: # Sue number
\s(\w+)\:\s(\d+), # info 1
\s(\w+)\:\s(\d+), # info 2
\s(\w+)\:\s(\d+) # info 3
"""
pattern = re.compile(parser, re.X | re.M)

for group in pattern.findall(inputStr):
    sueNumber, carac1, nb1, carac2, nb2, carac3, nb3 = group
    sue = {carac1: int(nb1), carac2: int(nb2), carac3: int(nb3)}
    if does_sue_match_criteria_part_1(sue, criteria):
        u.answer_part_1(sueNumber)
    if does_sue_match_criteria_part_2(sue, criteria):
        u.answer_part_2(sueNumber)
Exemplo n.º 5
0
        after_east_moves.append(new_row)
    after_south_moves = [[] for _ in range(len(current_step))]
    for col in range(len(current_step[0])):
        col_string = "".join(row[col] for row in after_east_moves)
        col_string = col_string.replace("v.", ".v")
        column = list(col_string)
        if after_east_moves[-1][col] == "v" and after_east_moves[0][col] == ".":
            column[0] = "v"
            column[-1] = "."
            changed = True
        for row, element in enumerate(column):
            after_south_moves[row].append(element)
    if not changed:
        changed = current_step != after_south_moves
    return after_south_moves, changed


def part_1(raw_input):
    state = [list(row) for row in raw_input.splitlines()]
    changed = True
    done_steps = 0
    while changed:
        state, changed = get_next_step(state)
        done_steps += 1
    return done_steps


u.assert_equals(part_1(example), 58)
u.answer_part_1(part_1(raw_input))
# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_
Exemplo n.º 6
0
        elif step == "se":
            q += 1
            s -= 1
        elif step == "sw":
            q -= 1
            r += 1
        elif step == "nw":
            q -= 1
            s += 1
    return int((abs(q) + abs(r) + abs(s)) / 2)


for path, distance in examples.items():
    u.assert_equals(get_distance_from_path(path), distance)

u.answer_part_1(get_distance_from_path(raw_input))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def get_further_during_path(path):
    q, r, s = 0, 0, 0
    further = 0
    for step in path.split(","):
        if step == "n":
            s += 1
            r -= 1
        elif step == "s":
            r += 1
            s -= 1
        elif step == "ne":
Exemplo n.º 7
0
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce"""

# part 1 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def count_easy_letters_in_output(raw_input):
    outputs = [row.split(" | ")[1] for row in raw_input.splitlines()]
    outputs = tuple(itertools.chain(*(r.split() for r in outputs)))
    return len(tuple(filter(lambda x: len(x) in (2, 4, 3, 7), outputs)))


u.assert_equals(count_easy_letters_in_output(example_input), 26)
u.answer_part_1(count_easy_letters_in_output(raw_input))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def output_sequence_from_entry(entry):
    all_sequences = tuple("".join(sorted(x))
                          for x in entry.split(" | ")[0].split(" "))
    outputs = tuple("".join(sorted(x))
                    for x in entry.split(" | ")[1].split(" "))

    one = next(x for x in all_sequences if len(x) == 2)
    four = next(x for x in all_sequences if len(x) == 4)
    seven = next(x for x in all_sequences if len(x) == 3)
    eight = next(x for x in all_sequences if len(x) == 7)
Exemplo n.º 8
0
            mask = line[7:]
        elif line.startswith("mem"):
            address, value = tuple(
                map(int,
                    re.findall(MEMORY_INSTRUCTION, line)[0]))
            bits = bits_from_integer(value)
            for i, mask_val in enumerate(reversed(mask)):
                if mask_val != "X":
                    bits[i] = mask_val
            memory[address] = bits_to_integer(bits)
    return sum(memory.values())


u.assert_equals(parse_input_to_program(example_program), 165)
u.assert_equals(parse_input_to_program(raw_input), 13496669152158)
u.answer_part_1(parse_input_to_program(raw_input))
# 13496669152158

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def parse_input_to_program_v2(raw_input):
    memory = defaultdict(lambda: 0)
    for line in raw_input.splitlines():
        if line.startswith("mask"):
            mask = line[7:]
        elif line.startswith("mem"):
            address, target_value = tuple(
                map(int,
                    re.findall(MEMORY_INSTRUCTION, line)[0]))
            bits = bits_from_integer(address)
Exemplo n.º 9
0
def find_corner_tiles(raw_tileset):
    contacts = build_contact_graph(raw_tileset)
    # in contacts graph:
    # - insider tiles have 4 neighbors
    # - border tiles have 3 neighbors
    # - corner tiles have 2 neighbors
    return [
        node
        for node in contacts.nodes()
        if len(list(nx.neighbors(contacts, node))) == 2
    ]


u.assert_equals(prod(find_corner_tiles(example_input)), 20899048083289)
u.answer_part_1(prod(find_corner_tiles(raw_input)))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_

TOP = 0
RIGHT = 1
BOTTOM = 2
LEFT = 3

DIRECTIONS = ("Top", "Right", "Bottom", "Left")


SEA_MONSTER = """
                  _ 
*    __    __    ^^>
 \  /  \  /  \  /   
Exemplo n.º 10
0
        next_sources = evolve_grid(grid, *source)
        sources.extend(next_sources)
    remove_floating_water(grid)


def count_wet_squares(grid: dict):
    min_x, max_x, min_y, max_y = find_min_max_clay_coordinates(grid)
    return sum(1 for x in range(min_x, max_x + 1)
               for y in range(min_y, max_y + 1) if grid[x, y] in ("~", "|"))


def count_resting_water_squares(grid: dict):
    min_x, max_x, min_y, max_y = find_min_max_clay_coordinates(grid)
    return sum(1 for x in range(min_x, max_x + 1)
               for y in range(min_y, max_y + 1) if grid[x, y] == "~")


example_grid = parse_input(example_input)
evolve_grid_until_everything_is_filled(example_grid)
u.assert_equals(count_wet_squares(example_grid), 57)

grid = parse_input(raw_input)
evolve_grid_until_everything_is_filled(grid)
draw_grid(grid)
u.answer_part_1(count_wet_squares(grid))
# 37277 is too low
# 38364 good answer, I was missing the "every x coordinate is valid"

u.assert_equals(count_resting_water_squares(example_grid), 29)
u.answer_part_2(count_resting_water_squares(grid))
Exemplo n.º 11
0
            if neighbor in path and self.is_small(neighbor):
                continue
            self.visit(neighbor, path.copy())


pf = PathFinder(example_10paths)
u.assert_equals(pf.find_all_paths(), 10)

pf = PathFinder(example_19paths)
u.assert_equals(pf.find_all_paths(), 19)

pf = PathFinder(example_226paths)
u.assert_equals(pf.find_all_paths(), 226)

pf = PathFinder(raw_input)
u.answer_part_1(pf.find_all_paths())

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


class ImprovedPathFinder(PathFinder):
    def visit(self, node, path, one_small_cave_visited_twice=False):
        path.append(node)
        if node == "end":
            self.finished_path(path)
            return
        for neighbor in nx.neighbors(self.graph, node):
            if neighbor == "start":
                continue
            if (
                one_small_cave_visited_twice
Exemplo n.º 12
0
            generate_regex_for_rule(subrule, rules)
            for subrule in rule.split(" | ")) + ")")


def check_validity_for_messages(raw_input: str):
    raw_rules, raw_messages = raw_input.split("\n\n")
    ruleset = generate_dict_from_raw_rules(raw_rules)
    regex_zero = re.compile(
        "^" + generate_regex_for_rule(ruleset["0"], ruleset) + "$",
        re.MULTILINE,
    )
    return len(regex_zero.findall(raw_messages))


u.assert_equals(check_validity_for_messages(example_input), 2)
u.answer_part_1(check_validity_for_messages(raw_input))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_

IMBRICATION_LEVEL = 5

raw_rules, _ = raw_input.split("\n\n")
ruleset = generate_dict_from_raw_rules(raw_rules)


def generate_regex_for_rule_part_2(rule: str, rules: dict, idx=0):
    if len(rule) == 3 and rule.count('"') == 2:
        return rule[1]
    if idx == "8" and rule == "42":
        # 8: 42 | 42 8 => 42 | 42 42 | 42 42 42…  so.. hop!  ⤵︎
        return generate_regex_for_rule_part_2("42", rules) + "+"
Exemplo n.º 13
0
    ]


def part_1(raw_input):
    algorithm, lines = parse_input(raw_input)
    if algorithm[0] == "1":
        default_on_odd_turns = "1"
    else:
        default_on_odd_turns = "0"
    lines = calculate_next_grid(lines, algorithm, default="0")
    lines = calculate_next_grid(lines, algorithm, default=default_on_odd_turns)
    return sum(row.count("1") for row in lines)


u.assert_equals(part_1(example), 35)
u.answer_part_1(part_1(raw_input))  # 5464! YAY

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def part_2(raw_input):
    algorithm, lines = parse_input(raw_input)
    if algorithm[0] == "1":
        default_on_odd_turns = "1"
    else:
        default_on_odd_turns = "0"
    for turn in range(50):
        print("█" * turn, turn, end="\r")
        default = default_on_odd_turns if turn % 2 == 1 else "0"
        lines = calculate_next_grid(lines, algorithm, default=default)
    print("\ndone!")
Exemplo n.º 14
0
    memorization.update(
        {number: [rank]
         for rank, number in enumerate(starting_numbers, 1)})
    last_spoken_number = starting_numbers[-1]
    for rank in range(len(starting_numbers) + 1, n + 1):
        if rank % 1000 == 0:
            print(rank, end="\r")
        if len(memorization[last_spoken_number]) >= 2:
            last_spoken_number = rank - 1 - memorization[last_spoken_number][-2]
        else:
            last_spoken_number = 0
        if rank == n:
            return last_spoken_number
        # maybe for memory optimization we could shorten the list here,
        # to keep only the 2 last indexes. But it worked for both parts
        # without the optimization, so…
        memorization[last_spoken_number].append(rank)


u.assert_equals(find_nth_number_in_drinking_game((0, 3, 6), 10), 0)

for starting_numbers, expected in examples.items():
    u.assert_equals(find_nth_number_in_drinking_game(starting_numbers, 2020),
                    expected)

u.answer_part_1(find_nth_number_in_drinking_game(my_input, 2020))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_

u.answer_part_2(find_nth_number_in_drinking_game(my_input, 30000000))
Exemplo n.º 15
0
                print("duh?")
        tiling[row, col] *= -1
    return tiling


def count_black_tiles(grid: dict):
    return list(grid.values()).count(-1)


example_tiling = extract_black_tiles(example)
u.assert_equals(count_black_tiles(example_tiling), 10)

tiling = extract_black_tiles(raw_input)
u.assert_equals(count_black_tiles(tiling), 317)

u.answer_part_1(count_black_tiles(tiling))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def count_black_neighbors(grid: defaultdict, coordinates: tuple):
    return [
        grid[coordinates] for coordinates in get_neighbors_coordinates(coordinates)
    ].count(-1)


def get_neighbors_coordinates(coordinates: tuple):
    row, col = coordinates
    neighbors_offsets = ((0, 2), (0, -2), (1, 1), (1, -1), (-1, -1), (-1, 1))
    for row_offset, col_offset in neighbors_offsets:
        yield row + row_offset, col + col_offset
Exemplo n.º 16
0
                state_graphs.add_edge(
                    current_state,
                    new_state,
                    weight=nx.shortest_path_length(
                        distances, position, target, weight="weight"
                    )
                    * COSTS[letter],
                )
        # print('────────────────────────────────────────────')
    # previous = None
    # for intermediary in nx.shortest_path(
    #    state_graphs, initial_state, TARGET, weight="weight"
    # ):
    #    debug_state(intermediary)
    #    if previous:
    #        print(state_graphs.edges[previous, intermediary])
    #    previous = intermediary
    return nx.shortest_path_length(state_graphs, initial_state, TARGET, weight="weight")


u.assert_equals(part_1(example_state), 44169)
# state_with_a_D_who_can_go_home = ('A', 'B', None, 'C', 'A', 'D', 'C', 'B', 'D', 'D', 'A', None, 'C', 'B', 'D', None, 'B', 'A', 'C', None, None, None, None)
# part_1(state_with_a_D_who_can_go_home)

my_initial_state = (
    (None,) * 7 + tuple("CDDB") + tuple("DCBA") + tuple("ABAD") + tuple("BACC")
)

u.answer_part_1(part_1(my_initial_state))
# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_
Exemplo n.º 17
0

u.assert_equals(get_place_coordinates("BFFFBBFRRR"), (70, 7))
u.assert_equals(get_place_coordinates("FFFBBBFRRR"), (14, 7))
u.assert_equals(get_place_coordinates("BBFFBBFRLL"), (102, 4))

u.assert_equals(get_place_id(70, 7), 567)
u.assert_equals(get_place_id(14, 7), 119)
u.assert_equals(get_place_id(102, 4), 820)

place_ids = [
    get_place_id(*get_place_coordinates(boarding_pass))
    for boarding_pass in raw_input.splitlines()
]

u.answer_part_1(max(place_ids))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_

sorted_place_ids = sorted(place_ids)

for i in range(1, len(sorted_place_ids) - 1):
    seat_id = sorted_place_ids[i]
    next_seat_id = sorted_place_ids[i + 1]
    if seat_id + 1 != next_seat_id:
        u.answer_part_2(seat_id + 1)
        break

# another method using a comprehension, but i'm not sure it's clearer
for seat_id, next_seat_id in ((sorted_place_ids[i:i + 2])
                              for i in range(len(sorted_place_ids) - 1)):
Exemplo n.º 18
0

def get_power_consumption(raw_input):
    rows = raw_input.splitlines()
    first_row = rows[0]
    width = len(first_row)
    length = len(rows)
    gamma_string = "".join(
        "0" if [r[bit] for r in rows].count("0") > length / 2 else "1"
        for bit in range(width))
    epsilon_string = "".join("0" if c == "1" else "1" for c in gamma_string)
    return int(gamma_string, 2) * int(epsilon_string, 2)


u.assert_equals(get_power_consumption(raw_example), 198)
u.answer_part_1(get_power_consumption(raw_input))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def get_life_support_rating(raw_input):
    rows = raw_input.splitlines()
    first_row = rows[0]
    width = len(first_row)
    length = len(rows)
    oxygen = rows.copy()
    co2 = rows.copy()
    for bit in range(width):
        o2_sum = sum(int(r[bit]) for r in oxygen)
        o2_criteria = str(int(o2_sum >= len(oxygen) / 2))
        oxygen = [r for r in oxygen if r[bit] == o2_criteria]
Exemplo n.º 19
0
    x, y, z = coordinates
    return -grid[x, y, z] + sum(grid[xn, yn, zn] for xn in range(x - 1, x + 2)
                                for yn in range(y - 1, y + 2)
                                for zn in range(z - 1, z + 2))


def boot_grid_for_6_cycles(raw_input):
    grid = build_grid_from_input(raw_input)
    for i in range(6):
        grid = build_new_grid(grid)
    return sum(grid.values())


u.assert_equals(boot_grid_for_6_cycles(example_input), 112)

u.answer_part_1(boot_grid_for_6_cycles(raw_input))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_

# Basically the same as part 1, with 4 dimensions:
# I copy-pasted and added "hyper" in function names.


def build_hyper_grid_from_input(input):
    rows = input.strip().splitlines()
    grid = defaultdict(
        int)  # grid[something] will be 0 if <something> is not defined
    for y, row in enumerate(rows):
        for x, char in enumerate(row):
            if char == "#":
                grid[x, y, 0, 0] = 1
Exemplo n.º 20
0
        elif length <= 1:
            list = list
        else:
            list = list[length - 1::-1] + list[length:]
        list = rotate(list, skip + length)
        total_rotation += skip + length
    return rotate(list, len(list) - (total_rotation % len(list)))


l = list(range(5))
u.assert_equals(apply_lengths(l, (3, 4, 1, 5)), [3, 4, 2, 1, 0])

l = list(range(256))
lengths = [int(x) for x in raw_input.split(",")]
l = apply_lengths(l, lengths)
u.answer_part_1(l[0] * l[1])
# 54990 too high

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def part_2(raw_input):
    lengths = [ord(char) for char in raw_input] + [17, 31, 73, 47, 23]
    sparse_hash = apply_lengths(list(range(256)), lengths * 64)
    dense_hash = [
        reduce(xor, sparse_hash[sl * 16:sl * 16 + 16]) for sl in range(16)
    ]
    return "".join(hex(number)[2:].rjust(2, "0") for number in dense_hash)


tests = {
Exemplo n.º 21
0
    height = len(grid)
    if axis == "y":  # horizontal fold
        if value != (height - 1) / 2:
            return
        new_grid = [[(grid[y][x] or grid[height - 1 - y][x])
                     for x in range(width)]
                    for y in range(int((height - 1) / 2))]
    elif axis == "x":  # vertical fold
        if value != ((width - 1) / 2):
            return
        new_grid = [[(row[x] or row[width - 1 - x])
                     for x in range(int((width - 1) / 2))] for row in grid]
    return new_grid


grid, folds = construct_grid(example)
new_grid = fold_grid(grid, folds[0])
new_grid = fold_grid(new_grid, folds[1])

grid, folds = construct_grid(raw_input)
new_grid = fold_grid(grid, folds.pop(0))
u.answer_part_1(sum(sum(1 if val else 0 for val in row) for row in new_grid))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_

for fold in folds:
    new_grid = fold_grid(new_grid, fold)

u.answer_part_2("RCPLAKHL")
debug_grid(new_grid)
Exemplo n.º 22
0
        new_scores = sum(score[pos] for pos in elves_position)
        score.extend(map(int, list(str(new_scores))))
        elves_position = [(pos + score[pos] + 1) % len(score)
                          for pos in elves_position]
        # debug_position(score, elves_position)
        if len(score) >= n + 10:
            break
    return "".join(map(str, (score[x] for x in range(n, n + 10))))


u.assert_equals(look_for_ten_recipes_after_nth(9), "5158916779")
u.assert_equals(look_for_ten_recipes_after_nth(5), "0124515891")
u.assert_equals(look_for_ten_recipes_after_nth(2018), "5941429882")
u.assert_equals(look_for_ten_recipes_after_nth(18), "9251071085")

u.answer_part_1(look_for_ten_recipes_after_nth(int(puzzle_input)))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def look_for_pattern_in_recipes(pattern: str):
    score = "37"
    elves_position = [0, 1]
    init = time()
    for i in count():
        if i % 10000 == 0:
            print(f"round {i} - len = {len(score)} - time = {time() - init}",
                  end="\r")
        new_scores = str(sum(int(score[pos]) for pos in elves_position))
        score += new_scores
        elves_position = [(pos + int(score[pos]) + 1) % len(score)
Exemplo n.º 23
0
iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
hcl:#cfa07d byr:1929

hcl:#ae17e1 iyr:2013
eyr:2024
ecl:brn pid:760753108 byr:1931
hgt:179cm

hcl:#cfa07d eyr:2025 pid:166559648
iyr:2011 ecl:brn hgt:59in
"""

u.assert_equals(count_valid_passports_in_batch(example_batch), 2)

u.answer_part_1(count_valid_passports_in_batch(raw_input))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_

# criteria which are easily regexable:
EASY_CRITERIA = tuple(
    map(
        lambda p: re.compile(p, re.M),
        (
            # hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f.
            # do the elves really define their hair color using hexcodes??
            r"hcl:#[0-9a-f]{6}\s",
            # ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth.
            r"ecl:(amb|blu|brn|gry|grn|hzl|oth)\s",
            #                 THIS ---------------^
            # pid (Passport ID) - a nine-digit number, including leading zeroes.
Exemplo n.º 24
0
    for row in raw_input.splitlines():
        value = int(row[-1:])
        dir = row[0]
        if dir == "f":
            x += value
        elif dir == "u":
            depth -= value
            if depth < 0:
                print("uh oh, flying submarine??")
        elif dir == "d":
            depth += value
    return x * depth


u.assert_equals(find_where_its_going(raw_example), 150)
u.answer_part_1(find_where_its_going(raw_input))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def calculate_with_aim(raw_input):
    x = 0
    depth = 0
    aim = 0
    for row in raw_input.splitlines():
        value = int(row[-1:])
        dir = row[0]
        if dir == "f":
            x += value
            depth += value * aim
        elif dir == "u":
Exemplo n.º 25
0
from itertools import product
from monad import monad
import utils as u

biggest_number = 0
for a in range(1, 10):
    print(f'{("▓" * a).ljust(10, "░")} biggestnumber = {biggest_number}',
          end="\r")
    for b, c, d, e, f, g, h, i, j, k, l, m, n in product(range(1, 10),
                                                         repeat=13):
        _, _, _, z = monad(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
        if z == 0:
            number = int("".join((a, b, c, d, e, f, g, h, i, j, k, l, m, n)))
            if number > biggest_number:
                biggest_number = number
                print(
                    f'{("▓" * a).ljust(10, "░")} biggestnumber = {biggest_number}',
                    end="\r",
                )

print("")
u.answer_part_1(biggest_number)
Exemplo n.º 26
0
def compute_scanning_error_rate(raw_notes, valid_values):
    rows = raw_notes.splitlines()
    nearby_tickets_row = rows.index("nearby tickets:")
    invalid_values = []
    for raw_ticket in rows[nearby_tickets_row + 1:]:
        invalid_values.extend(value
                              for value in map(int, raw_ticket.split(","))
                              if value not in valid_values)
    return sum(invalid_values)


valid_values = extract_valid_values_from_raw_input(example_input)
u.assert_equals(compute_scanning_error_rate(example_input, valid_values), 71)

my_valid_values = extract_valid_values_from_raw_input(raw_input)
u.answer_part_1(compute_scanning_error_rate(raw_input, my_valid_values))
# 16908 too low: i will try use a list instead of a set

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def extract_valid_tickets(raw_notes, valid_values):
    rows = raw_notes.splitlines()
    nearby_tickets_row = rows.index("nearby tickets:")
    for raw_ticket in rows[nearby_tickets_row + 1:]:
        int_ticket = tuple(map(int, raw_ticket.split(",")))
        if all(value in valid_values for value in int_ticket):
            yield (int_ticket)


def extract_my_ticket_from_raw_input(raw_input):
Exemplo n.º 27
0
u.assert_equals(sumOfAllNumbers("[1,2,3]"), 6)
u.assert_equals(sumOfAllNumbers('{"a":2,"b":4}'), 6)

# [[[3]]] and {"a":{"b":4},"c":-1} both have a sum of 3.
u.assert_equals(sumOfAllNumbers("[[[3]]]"), 3)
u.assert_equals(sumOfAllNumbers('{"a":{"b":4},"c":-1}'), 3)

# {"a":[-1,1]} and [-1,{"a":1}] both have a sum of 0.
u.assert_equals(sumOfAllNumbers('{"a":[-1,1]}'), 0)
u.assert_equals(sumOfAllNumbers('[-1,{"a":1}]'), 0)

# [] and {} both have a sum of 0.
u.assert_equals(sumOfAllNumbers("[]"), 0)
u.assert_equals(sumOfAllNumbers(r"{}"), 0)

u.answer_part_1(sumOfAllNumbers(inputStr))

u.assert_equals(4,
                sumOfAllNumbers(removeRedObjects('[1,{"c":"red","b":2},3]')))
u.assert_equals(
    sumOfAllNumbers(removeRedObjects('{"d":"red","e":[1,2,3,4],"f":5}')), 0)

inputStrWithoutRed = removeRedObjects(inputStr)
u.answer_part_2(sumOfAllNumbers(inputStrWithoutRed))
# part2 85717 too high
# part2 68466 yay!

# Ignore any object (and all of its children) which has any property with the value "red".
# Do this only for objects ({...}), not arrays ([...]).
# [1,2,3] still has a sum of 6.
# [1,{"c":"red","b":2},3] now has a sum of 4, because the middle object is ignored.
Exemplo n.º 28
0
        r"([a-z]+) (inc|dec) (-?\d+) if ([a-z]+) ([<>=!]+) (-?\d+)")
    registries = defaultdict(lambda: 0)
    for row in raw_input.splitlines():
        m = reg.match(row)
        groups = m.groups()
        if interpret_condition(groups[3:], registries):
            registry, action, value = groups[:3]
            if action == "dec":
                registries[registry] -= int(value)
            elif action == "inc":
                registries[registry] += int(value)
    return max(registries.values())


u.assert_equals(interpret_instructions(example), 1)
u.answer_part_1(interpret_instructions(raw_input))

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def interpret_instructions_part_2(raw_input):
    reg = re.compile(
        r"([a-z]+) (inc|dec) (-?\d+) if ([a-z]+) ([<>=!]+) (-?\d+)")
    registries = defaultdict(lambda: 0)
    max_ever = 0
    for row in raw_input.splitlines():
        m = reg.match(row)
        groups = m.groups()
        if interpret_condition(groups[3:], registries):
            registry, action, value = groups[:3]
            if action == "dec":
Exemplo n.º 29
0

example_cups = deque(map(int, list(example_labeling)))
example_cups = crab_moves_cups(example_cups)
u.assert_equals("".join(map(str, example_cups)), "837419265")


my_cups = deque(map(int, list(my_labeling)))
cups_after_100_moves = crab_moves_cups(my_cups, 100)
index_of_one = cups_after_100_moves.index(1)
cups_after_100_moves.rotate(-index_of_one)  # put 1 at the beginning of the deque
cups_after_100_moves.popleft()  # remove the one
answer_part_1 = "".join(map(str, cups_after_100_moves))

u.assert_equals(answer_part_1, "25368479")
u.answer_part_1(answer_part_1)

# # part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def build_chained_list(seed: str, length: int):
    """instead of storing every cup in order, store every cup with the label of the
    next cup in the circle"""
    d = dict()
    seed = list(map(int, list(seed)))
    current = seed[0]
    for i, value in enumerate(seed[:-1]):
        d[value] = seed[i + 1]
    if length > len(seed):
        # last cup of the seed is next to the first "extension" cup
        d[seed[-1]] = len(seed) + 1
Exemplo n.º 30
0
        # print(f"------ ROUND {i} -----------")
        army.targeting_phase()
        something_happened = army.attack_phase()
        counted_groups = dict(army.counting_groups())
        if not something_happened:
            print("nothing happens")
            break
        # print(counted_groups)
        if 0 in counted_groups.values():
            break
    return max(counted_groups.values())


u.assert_equals(fight(example), 5216)

u.answer_part_1(fight(raw_input))
# 30454 too high
# 25241 too high
# 25241 again
# 23385 !

# part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_


def boosted_fight(input_str, boost):
    army = Army(f"xxxx")
    side = "Immune System"
    for row in filter(None, input_str.splitlines()):
        if row == "Immune System:":
            side = "Immune System"
        elif row == "Infection:":