def solve_part2(file_name): pos_y, pos_x, w_pos_y, w_pos_x = 0, 0, 1, 10 def rotate(deg): deg_rad = radians(deg) return ( round(cos(deg_rad) * w_pos_x - sin(deg_rad) * w_pos_y), round(sin(deg_rad) * w_pos_x + cos(deg_rad) * w_pos_y), ) for instruction in read_line_separated_list(file_name): opr, val = instruction[:1], int(instruction[1:]) if opr == "L": w_pos_x, w_pos_y = rotate(val) elif opr == "R": w_pos_x, w_pos_y = rotate(-val) elif opr == "F": pos_x += w_pos_x * val pos_y += w_pos_y * val elif opr == "N": w_pos_y += val elif opr == "S": w_pos_y -= val elif opr == "E": w_pos_x += val elif opr == "W": w_pos_x -= val return int(abs(pos_x) + abs(pos_y))
def _find_which_allergens_each_ingredient_cant_be(file_name): allergens = defaultdict(set) ingredients = defaultdict(set) possible_ing_per_allergen = defaultdict(set) for i, line in enumerate(read_line_separated_list(file_name)): _ingredients, _allergens = pattern_extract( "(\w+(?: \w+)+) \(contains (\w+(?:, \w+)*)\)", line, str, str) for ing in _ingredients.split(): ingredients[ing].add(i) for al in _allergens.split(", "): allergens[al].add(i) possible_ing_per_allergen[al].update(_ingredients.split()) cant_be_allergen = defaultdict(set) for ing, ing_in_recipe in ingredients.items(): for al, al_in_recipe in allergens.items(): if a_is_subset_of_b(al_in_recipe, ing_in_recipe): continue cant_be_allergen[ing].add(al) for ing, _cant_be_allergen in cant_be_allergen.items(): for al in _cant_be_allergen: if ing in possible_ing_per_allergen[al]: possible_ing_per_allergen[al].remove(ing) return ingredients, cant_be_allergen, possible_ing_per_allergen
def solve_part2(file_name): seats = sorted(read_line_separated_list(file_name, cast_to=compute_seat_id)) for x, y in zip(seats, seats[1:]): if y != x + 1: return x + 1 return -1
def _read_and_compute_diffs(file_name): jolts = sorted(read_line_separated_list(file_name, int)) jolts = [0, *jolts, jolts[-1] + 3] diffs = [] for x, y in zip(jolts, jolts[1:]): diffs.append(y - x) return diffs
def _read_and_parse_instructions(file_name): for row in read_line_separated_list(file_name): res = pattern_extract("(mem)\[(\d+)\] = (\d+)", row, str, int, int) if res is None: name, val = row.split(" = ") yield [name, val] else: yield res
def _get_start_tiles(file_name): tiles = defaultdict(lambda: False) for line in read_line_separated_list(file_name): pos = (0, 0) for ins in map(first, pattern_extract_all("(se|sw|ne|nw|e|w)", line, str)): pos = add_tuples(pos, directions[ins]) tiles[pos] = not tiles[pos] return tiles
def solve_part2(file_name): text = read_line_separated_list(file_name) contains = defaultdict(list) for line in text: head, tail = line.split(" bags contain ") contains[head].extend( pattern_extract_all("(\d+) (\w+ \w+) bags?", tail, int, str)) return _cost_of_bag("shiny gold", 1, contains) - 1
def solve_part1(file_name): schedule = read_line_separated_list(file_name) earlist_ts = int(schedule[0]) buses = list(flatten(pattern_extract_all("(\d+)", schedule[1], int))) ts = earlist_ts while 1: for b in buses: if ts % b == 0: return (ts - earlist_ts) * b ts += 1
def solve_part1(file_name): lines = read_line_separated_list(file_name) lines = filter(lambda l: l.strip(), lines) cards_pk, doors_pk = map(int, lines) i = 1 while transform(i, 7) != cards_pk and transform(i, 7) != doors_pk: i += 1 if transform(i, 7) == cards_pk: return transform(i, doors_pk) return transform(i, cards_pk)
def solve_part1(file_name): text = read_line_separated_list(file_name) contained_by = defaultdict(list) for line in text: head, tail = line.split(" bags contain ") for rule in pattern_extract_all("\d+ (\w+ \w+) bags?", tail, str): contained_by[rule[0]].append(head) seen = set() q = ["shiny gold"] while q: node = q.pop() seen.add(node) for other_node in contained_by.get(node, []): if other_node not in seen: q.append(other_node) return len(seen) - 1
def solve_part2(file_name): board = read_line_separated_list(file_name) n_rows, n_cols = len(board), len(board[0]) while 1: board_str = "\n".join(board) updated_board = [] for r in range(n_rows): row = "" for c in range(n_cols): row += _get_new_state2(board, r, c, n_rows, n_cols) updated_board.append(row) if board_str == "\n".join(updated_board): break board = updated_board return Counter(board_str)["#"]
def solve_part1(file_name): direction, pos_y, pos_x = 0, 0, 0 for instruction in read_line_separated_list(file_name): opr, val = instruction[:1], int(instruction[1:]) if opr == "L": direction += val elif opr == "R": direction -= val elif opr == "F": direction_rad = radians(direction) pos_x += round(cos(direction_rad) * val) pos_y += round(sin(direction_rad) * val) elif opr == "N": pos_y += val elif opr == "S": pos_y -= val elif opr == "E": pos_x += val elif opr == "W": pos_x -= val return int(abs(pos_x) + abs(pos_y))
def solve_part2(file_name): texts = read_line_separated_list(file_name) total = 0 for line in texts: total += solve2(line) return total
def solve_part2(file_name): return quantify(read_line_separated_list(file_name), pred=_is_valid_password2)
def solve_part1(file_name): return max(read_line_separated_list(file_name, cast_to=compute_seat_id))
def solve_part1(file_name): wood = read_line_separated_list(file_name) return _count_trees(wood, (1, 3))
def solve_part2(file_name, prev_n=25): numbers = read_line_separated_list(file_name, int) n = _first_with_no_combo_in_prev_n(numbers, prev_n) i, j = _find_contiguous_sum(numbers, n) return max(numbers[i:j]) + min(numbers[i:j])
def solve_part1(file_name, prev_n=25): numbers = read_line_separated_list(file_name, int) return _first_with_no_combo_in_prev_n(numbers, prev_n)
def product_where_sum_of_combo_equals_n(combo_length, n, file_name): values = read_line_separated_list(file_name, int) return multiply( first_true(combinations(values, combo_length), pred=lambda c: sum(c) == n))
def solve_part2(file_name): buses = read_line_separated_list(file_name)[1].split(",") modulus, remainders = map( list, unzip((int(x), -i) for i, x in enumerate(buses) if x != "x")) return chinese_remainder(modulus, remainders)
def solve_part2(file_name): wood = read_line_separated_list(file_name) return multiply([ _count_trees(wood, s) for s in [(1, 1), (1, 3), (1, 5), (1, 7), (2, 1)] ])