found_first_group_size = True first_group_candidates.append(first_group) if found_first_group_size: break return min(map(math.prod, first_group_candidates)) u.assert_equals(balancing_packages_into_three(example_packages), 99) u.answer_part_1(balancing_packages_into_three(package_list)) # part 2 def balancing_packages_into_four(packages: tuple): total_weight = sum(packages) if total_weight % 4 > 0: raise RuntimeError("Impossible to balance the load, christmas is doomed!") group_weight = total_weight // 4 found_first_group_size = False first_group_candidates = [] for first_group_size in range(1, len(packages)): for first_group in itertools.combinations(packages, first_group_size): if sum(first_group) == group_weight: found_first_group_size = True first_group_candidates.append(first_group) if found_first_group_size: break return min(map(math.prod, first_group_candidates)) u.assert_equals(balancing_packages_into_four(example_packages), 44) u.answer_part_2(balancing_packages_into_four(package_list))
hcl:#888785 hgt:164cm byr:2001 iyr:2015 cid:88 pid:545766238 ecl:hzl eyr:2022 iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719""".split( "\n\n"): u.assert_equals(is_this_valid_data(valid_passport), True) for invalid_passport in """eyr:1972 cid:100 hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926 iyr:2019 hcl:#602927 eyr:1967 hgt:170cm ecl:grn pid:012533040 byr:1946 hcl:dab227 iyr:2012 ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277 hgt:59cm ecl:zzz eyr:2038 hcl:74454a iyr:2023 pid:3556412378 byr:2007""".split("\n\n"): u.assert_equals(is_this_valid_data(invalid_passport), False) u.answer_part_2( sum(1 for row in filter(is_this_a_valid_passport, raw_input.split("\n\n")) if is_this_valid_data(row))) # 185 too high # 110 too high
# [[[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. # {"d":"red","e":[1,2,3,4],"f":5} now has a sum of 0, because the entire structure is ignored. # [1,"red",5] has a sum of 6, because "red" in an array has no effect.
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": r -= 1 q += 1 elif step == "se": q += 1 s -= 1 elif step == "sw": q -= 1 r += 1 elif step == "nw": q -= 1 s += 1 current_position = int((abs(q) + abs(r) + abs(s)) / 2) if current_position > further: further = current_position return further u.answer_part_2(get_further_during_path(raw_input))
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)
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": registries[registry] -= int(value) elif action == "inc": registries[registry] += int(value) if registries[registry] > max_ever: max_ever = registries[registry] return max_ever u.assert_equals(interpret_instructions_part_2(example), 10) u.answer_part_2(interpret_instructions_part_2(raw_input))
6: 28, 7: 41, 8: 37, 9: 49, 10: 37, 20: 132, 30: 259, 40: 406, 50: 566, 60: 788, 70: 1106, 80: 1373, 90: 1844, 100: 2208, } for days in range(1, 101): example_tiling = build_next_grid(example_tiling) if days in tests: u.assert_equals( count_black_tiles(example_tiling), tests[days], f" black tiles after {days} days", ) for days in range(100): tiling = build_next_grid(tiling) u.answer_part_2(count_black_tiles(tiling)) # 3822 too high because I did only 99 days DUH
24: 14 1 abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa bbabbbbaabaabba babbbbaabbbbbabbbbbbaabaaabaaa aaabbbbbbaaaabaababaabababbabaaabbababababaaa bbbbbbbaaaabbbbaaabbabaaa bbbababbbbaaaaaaaabbababaaababaabab ababaaaaaabaaab ababaaaaabbbaba baabbaaaabbaaaababbaababb abbbbabbbbaaaababbbbbbaaaababb aaaaabbaabaaaaababaa aaaabbaaaabbaaa aaaabbaabbaaaaaaabbbabbbaaabbaabaaa babaaabbbaaabaababbaabababaaab aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba""" u.assert_equals(check_validity_for_messages_part_2(new_example), 12) u.answer_part_2(check_validity_for_messages_part_2(raw_input)) # needed imbrication level 5 for example to work. # it was the minimum for getting the good answer on actual input. # result = 296 with imbrication level 5 & more # result = 12 with imbrication level 1 # 261 with imbrication 2 # 285 with imbrication 3 # 295 with imbrication 4
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))
# to first check the combinations which have a greater chance to remove a lot # of characters. for index in [m.start() for m in re.finditer(mol_to, molecule)]: new_molecule = molecule[:index] + molecule[index:].replace( mol_to, # reversed vs. part 1 (mol_to replaced with mol_from) mol_from, 1, ) graph.add_edge(molecule, new_molecule) if new_molecule not in examined_molecules: if len(new_molecule) <= shortest_molecule_achieved: # hm! short molecule! interesting! # we append on the right, to pick it first later shortest_molecule_achieved = len(new_molecule) molecules_to_reduce.append(new_molecule) continue # in that case, the molecule may be less interesting to examine, # we append on the other side molecules_to_reduce.appendleft(new_molecule) # And now the answer we're looking for: ------------------------- # In the new graph, look for the shortest path between target and the electron. # It's almost too easy with networkx. (The hard part was to build the graph, though) return -1 + len(nx.shortest_path(graph, target_molecule, "e")) u.assert_equals(reduce_molecule("HOH", example_replacements), 3) u.assert_equals(reduce_molecule("HOHOHO", example_replacements), 6) u.answer_part_2(reduce_molecule(molecule, replacements))
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))
counted_groups = dict(army.counting_groups()) for counter in count(): army.targeting_phase() something_happened = army.attack_phase() if not something_happened: print("blah, nothing happened this phase") break army.cleaning_phase() counted_groups = dict(army.counting_groups()) if 0 in counted_groups.values(): print(f"phew! fight is over after {counter} rounds") break print(counted_groups) return max(counted_groups.values()), counted_groups["Infection"] == 0 u.assert_equals(boosted_fight(example, 0), (5216, False)) u.assert_equals(boosted_fight(example, 1570), (51, True)) u.assert_equals(boosted_fight(raw_input, 0), (23385, False)) for i in range(85, 100): remaining, immune_has_won = boosted_fight(raw_input, i) if immune_has_won: u.answer_part_2(f"{remaining} units with a boost of {i}") break # boosted_fight(raw_input, 92) # 3516 too high with boost 92 # 2344 units with boost 88 ?
drawing.line((fix_x(xa), fix_y(ya), fix_x(xb), fix_y(yb)), fill=room_color, width=3) drawing.regular_polygon((fix_x(0), fix_y(0) + 1, w - 3), 3, fill=(200, 0, 0)) imgFile.show() for regex, expected in examples.items(): map = build_map_from_regex(regex) path_lengths = calculate_shortest_paths(map) u.assert_equals(max(path_lengths.values()), expected) map = build_map_from_regex(raw_input) draw_map(map) # whoa, this place is HUGE indeed print(f"calculating path lengths...") init_time = time() path_lengths = calculate_shortest_paths(map) print(f"Done! It took {time() - init_time:.2f} seconds.") max_length = max(path_lengths.values()) u.assert_equals(max_length, 3885) u.answer_part_1(max_length) # 3885 # part 2 -'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,__,.-'*'-.,_ u.answer_part_2(sum(1 for length in path_lengths.values() if length >= 1000))
get_number_of_gifts(991) # I tried using an increment of 410 to have numbers which # N/2 and N/3 and N/7 and N/4 would be in the sum… # It gave me answer 1330560 which is too high. starting_point = 95970 increment = 6 max_gifts = 1377855 TARGET = 36000000 init_time = time.time() # use 210 increment so we are targeting multiples of 2 and 3 and 5 and 7, # so N/2 and N/3 and n/5 and n/7 will be in the sum for i in range(starting_point, starting_point + 3200 * increment, increment): gifts = get_number_of_gifts(i) print( f"------ house {i} - {gifts:08} gifts - time {time.time() - init_time} -------", end="\r", ) if max_gifts < gifts: max_gifts = gifts print("") if gifts > TARGET: print("\n") u.answer_part_2(i) break print(f"\ntime {time.time() - init_time}")
import utils as u # Solution inspired by the subreddit: # instead of calculating the number of gifts from the house number, # loop on the elves and have them "deliver presents" and store the # amount of presents in every house. max_houses = 36000000 house_limit_per_elf = 50 target = 36000000 points = [0] * max_houses max_points = 0 for elf in range(1, max_houses): for house in range(elf, elf * (house_limit_per_elf + 1), elf): # print(f"elf {elf} fills house {house}") if house < max_houses: points[house] += 11 * elf if points[elf] > max_points: # the house with the same number as the elf will not be filled more, # hence the check on points[elf] print(f"{points[elf]} in house {elf}") max_points = points[elf] if points[elf] >= target: print("") u.answer_part_2(elf) break
for neighbor in nx.neighbors(self.graph, node): if neighbor == "start": continue if ( one_small_cave_visited_twice and neighbor in path and self.is_small(neighbor) ): continue elif ( not one_small_cave_visited_twice and neighbor in path and self.is_small(neighbor) ): self.visit(neighbor, path.copy(), True) continue self.visit(neighbor, path.copy(), one_small_cave_visited_twice) pf = ImprovedPathFinder(example_10paths) u.assert_equals(pf.find_all_paths(), 36) pf = ImprovedPathFinder(example_19paths) u.assert_equals(pf.find_all_paths(), 103) pf = ImprovedPathFinder(example_226paths) u.assert_equals(pf.find_all_paths(), 3509) pf = ImprovedPathFinder(raw_input) u.answer_part_2(pf.find_all_paths())
for k, v in fields_possible_positions.items() if len(v) > 0 } # And now we have the positions, do not forget to map them to the values... fields_values = { key: my_ticket[position] for key, position in fields_positions.items() } return fields_values example_input = """class: 0-1 or 4-19 row: 0-5 or 8-19 seat: 0-13 or 16-19 your ticket: 11,12,13 nearby tickets: 3,9,18 15,1,5 5,14,9""" example_values = relate_fields_to_values_in_ticket(example_input) u.assert_equals(example_values, {"class": 12, "row": 11, "seat": 13}) my_values = relate_fields_to_values_in_ticket(raw_input) u.answer_part_2( prod(val for key, val in my_values.items() if key.startswith("departure"))) # 45696 too low (I made a product of the positions instead of the values, duh) # 1307550234719 is the right answer, indeed the previous one was too low
for i, mask_val in enumerate(mask[::-1]): if mask_val == "1": bits[i] = "1" elif mask_val == "X": floating_bits.add(i) for values in itertools.product(*[["0", "1"]] * len(floating_bits)): target_bits = bits.copy() for index, value in zip(floating_bits, values): target_bits[index] = value target_addresses.add(bits_to_integer(target_bits)) # print( # f"writing {target_value} in {', '.join(map(str,sorted(target_addresses)))}" # ) for target_address in target_addresses: memory[target_address] = target_value return sum(memory.values()) example_program_v2 = """mask = 000000000000000000000000000000X1001X mem[42] = 100 mask = 00000000000000000000000000000000X0XX mem[26] = 1""" u.assert_equals(parse_input_to_program_v2(example_program_v2), 208) u.answer_part_2(parse_input_to_program_v2(raw_input)) # 3279437161092 not the right answer # 2851461851581 is too low # 3278997609887 right answer for part 2
off x=2032..69770,y=-71013..4824,z=7471..94418 on x=43670..120875,y=-42068..12382,z=-24787..38892 off x=37514..111226,y=-45862..25743,z=-16714..54663 off x=25699..97951,y=-30668..59918,z=-15349..69697 off x=-44271..17935,y=-9516..60759,z=49131..112598 on x=-61695..-5813,y=40978..94975,z=8655..80240 off x=-101086..-9439,y=-7088..67543,z=33935..83858 off x=18020..114017,y=-48931..32606,z=21474..89843 off x=-77139..10506,y=-89994..-18797,z=-80..59318 off x=8476..79288,y=-75520..11602,z=-96624..-24783 on x=-47488..-1262,y=24338..100707,z=16292..72967 off x=-84341..13987,y=2429..92914,z=-90671..-1318 off x=-37810..49457,y=-71013..-7894,z=-105357..-13188 off x=-27365..46395,y=31009..98017,z=15428..76570 off x=-70369..-16548,y=22648..78696,z=-1892..86821 on x=-53470..21291,y=-120233..-33476,z=-44150..38147 off x=-93533..-4276,y=-16170..68771,z=-104985..-24507""" u.assert_equals(part_2(example_1), 39) u.assert_equals(part_2(example_2), 590784) example_handcrafted = """on x=1..10,y=1..10,z=1..10 on x=1..2,y=1..2,z=1..2 off x=1..2,y=1..2,z=1..2 off x=1..10,y=1..10,z=1..10""" u.assert_equals(part_2(example_handcrafted), 0) u.assert_equals(part_2(example_3), 2758514936282235) u.answer_part_2(part_2(raw_input))
# u.assert_equals(t.borders[LEFT], "efgh", "left border after rotation") # t.flip(LEFT) # u.assert_equals(t.borders[TOP], "hd84", "top border after flip/horiz axis") # u.assert_equals(t.borders[RIGHT], "4321", "right border after flip/horiz axis") # u.assert_equals(t.borders[BOTTOM], "ea51", "bottom border after flip/horiz axis") # u.assert_equals(t.borders[LEFT], "hgfe", "left border after flip/horiz axis") # t.flip(TOP) # u.assert_equals(t.borders[TOP], "48dh", "top border after flip/vertical axis") # u.assert_equals(t.borders[RIGHT], "hgfe", "right border after flip/vertical axis") # u.assert_equals(t.borders[BOTTOM], "15ae", "bottom border after flip/vertical axis") # u.assert_equals(t.borders[LEFT], "4321", "left border after flip/vertical axis") tiles = build_tile_objects_dict(raw_input) graph = build_contact_graph(raw_input) analyze_graph(graph) assemble_jigsaw(tiles, graph) display_assembled_tile_ids(tiles) print("------") i_map = extract_assembled_map(tiles) sea = Map(i_map) look_for_sea_monsters(sea) u.answer_part_2(str(sea).count("#")) # 2534 too high
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)): if seat_id + 1 != next_seat_id: u.answer_part_2(seat_id + 1) break
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] if len(oxygen) == 1: break for bit in range(width): co2_sum = sum(int(r[bit]) for r in co2) co2_criteria = str(int(co2_sum < len(co2) / 2)) co2 = [r for r in co2 if r[bit] == co2_criteria] if len(co2) == 1: break return int(oxygen[0], 2) * int(co2[0], 2) u.assert_equals(get_life_support_rating(raw_example), 230) u.answer_part_2(get_life_support_rating(raw_input))
top_right_segment = next(x for x in eight if x not in six) two = next(x for x in five_characters if top_right_segment in x) five = next(x for x in five_characters if top_right_segment not in x) values = { zero: "0", one: "1", two: "2", three: "3", four: "4", five: "5", six: "6", seven: "7", eight: "8", nine: "9", } return int("".join(values[x] for x in outputs)) def sum_output_of_sequences(raw_input): return sum( output_sequence_from_entry(entry) for entry in raw_input.splitlines()) example_entry = "acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf" u.assert_equals(output_sequence_from_entry(example_entry), 5353) u.assert_equals(sum_output_of_sequences(example_input), 61229) u.answer_part_2(sum_output_of_sequences(raw_input))
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) for pos in elves_position] if pattern in score[-7:]: print(f"round {i} - len = {len(score)} - time = {time() - init}") return score.index(pattern) u.assert_equals(look_for_pattern_in_recipes("51589"), 9) u.assert_equals(look_for_pattern_in_recipes("01245"), 5) u.assert_equals(look_for_pattern_in_recipes("92510"), 18) u.assert_equals(look_for_pattern_in_recipes("59414"), 2018) u.answer_part_2(look_for_pattern_in_recipes(puzzle_input))
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)
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": aim -= value elif dir == "d": aim += value return x * depth u.assert_equals(calculate_with_aim(raw_example), 900) u.answer_part_2(calculate_with_aim(raw_input))
# 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)
next_direction = NORTH elif current_direction == WEST: if x == -y: next_direction = SOUTH elif x == y: if x > 0: next_direction = WEST elif x < 0: next_direction = EAST dx, dy = next_direction return next_direction, x + dx, y + dy def part_2(target): x = 0 y = 0 values = defaultdict(lambda: 0) values[0, 0] = 1 direction = EAST for _ in count(1): direction, x, y = next_position(direction, x, y) current_value = sum(values[x, y] for x, y in product(range(x - 1, x + 2), range(y - 1, y + 2))) values[x, y] = current_value if current_value > target: return current_value u.answer_part_2(part_2(input))
if destination < mini: destination = maxi destination_clockwise = cups[destination] cups[destination] = picked[0] cups[picked[2]] = destination_clockwise current = cups[current] return cups example_chained_list = build_chained_list("389125467", 9) new_chained_list = crab_moves_cups_but_faster(example_chained_list, 3, 10) u.assert_equals(cups_to_str(new_chained_list, 8), "837419265") u.blue("now try with bigger lists...") example_BIG_list = build_chained_list("389125467", 1000000) BIG_list_after_10M_moves = crab_moves_cups_but_faster(example_BIG_list, 3, 10000000) u.assert_equals(BIG_list_after_10M_moves[1], 934001) u.assert_equals(BIG_list_after_10M_moves[934001], 159792) my_BIG_list = build_chained_list(my_labeling, 1000000) my_list_after_10M_moves = crab_moves_cups_but_faster( my_BIG_list, int(my_labeling[0]), 10000000 ) clockwise_1st_position = my_list_after_10M_moves[1] clockwise_2nd_position = my_list_after_10M_moves[clockwise_1st_position] u.answer_part_2(clockwise_1st_position * clockwise_2nd_position)
try: situation = todo_list.pop() except IndexError: print(f"todo list is empty at iteration {i}") break if situation.spent_mp > cheapest_victory_cost: continue if is_victory(situation) == V: if situation.spent_mp < cheapest_victory_cost: print(situation.cast_spells) cheapest_victory_cost = situation.spent_mp print(f"cheapest victory cost: {cheapest_victory_cost}") print("---------") continue elif is_victory == D: continue for next_situation in find_neighbor_situations(situation): todo_list.append(next_situation) u.assert_equals(cheapest_victory_cost, 1289) # cf pompage.py u.answer_part_2(cheapest_victory_cost) # 1408 too high 296455 iterations # 1295 too high 4563918 iterations, I keep finding this one # 847 too low 2980515 iterations # 900 WRONG 4230201 iterations # 1295: # recharge • poison • shield • missile • missile • recharge • poison • shield • missile • missile • missile # 1289: # Poison -> Magic Missile -> Recharge -> Poison -> Shield -> Recharge -> Poison -> Drain -> Drain