return len(valid_pairs) > 0 preamble_start = 0 for idx in range(preamble_len, len(numbers)): if not is_valid(numbers[idx], numbers[preamble_start:preamble_start + preamble_len]): return numbers[idx] preamble_start += 1 return None def find_encryption_weakness(numbers, expected_sum): for sublist_len in range(2, len(numbers) - 1): for idx in range(len(numbers) - sublist_len + 1): sublist = numbers[idx:idx + sublist_len] if sum(sublist) == expected_sum: return min(sublist) + max(sublist) return None test_numbers = read_list_of_ints('test') invalid_test_value = find_invalid_value(test_numbers, preamble_len=5) assert_eq(127, invalid_test_value) assert_eq(62, find_encryption_weakness(test_numbers, invalid_test_value)) numbers = read_list_of_ints('input') invalid_value = find_invalid_value(numbers, preamble_len=25) print(f"invalid number: {invalid_value}") print( f"encryption weakness: {find_encryption_weakness(numbers, invalid_value)}")
row = binary_search(line[:8], 0, 127, "F") column = binary_search(line[7:], 0, 7, "L") seat_id = row * 8 + column decoded.append((line, row, column, seat_id)) return decoded def my_seat_id(decoded): seat_ids = list(map(lambda t: t[3], decoded)) for x in range(0, len(seat_ids) - 1): if seat_ids[x] - seat_ids[x + 1] == 2: return seat_ids[x] - 1 return -1 tests = [ ("BFFFBBFRRR", 70, 7, 567), ("FFFBBBFRRR", 14, 7, 119), ("BBFFBBFRLL", 102, 4, 820), ] for test in tests: assert_eq(test, decode_lines([test[0]])[0]) lines = read_lines('input') decoded = decode_lines(lines) decoded.sort(key=lambda t: t[3], reverse=True) print(f"Max seat_id: {decoded[0][3]}") print(f"My seat_id: {my_seat_id(decoded)}")
acc = next_acc cmd_idx = next_cmd_idx return cmd_idx, acc def fix(program): def replace(prog, i): if prog[i][0] == "nop": prog[i] = "jmp", prog[i][1] elif prog[i][0] == "jmp": prog[i] = "nop", prog[i][1] for idx in range(len(program)): replace(program, idx) last_idx, acc = compute(program) if last_idx < len(program): replace(program, idx) else: return acc return None test_program = parse_program(read_lines('test')) assert_eq(5, compute(test_program)[1]) assert_eq(8, fix(test_program)) program = parse_program(read_lines('input')) print(f"acc before loop starts: {compute(program)[1]}", ) print(f"acc after program fix: {fix(program)}", )
for i, x in enumerate(ids.split(',')): if x == 'x': continue nr = int(x) elements.append((i, nr)) max_elem = max(elements, key=lambda e: e[1]) elements = list(map(lambda e: (e[0] - max_elem[0], e[1]), elements)) cur = 0 while not is_valid(elements, cur): cur += max_elem[1] et = time.time() print(f"{cur} in {(et - st)}") return cur + elements[0][0] assert_eq(295, part1(load('test'))) print(f"waitime = {part1(load('input'))}") assert_eq(1068781, part2('7,13,x,x,59,x,31,19')) assert_eq(3417, part2('17,x,13,19')) assert_eq(754018, part2('67,7,59,61')) assert_eq(779210, part2('67,x,7,59,61')) assert_eq(1261476, part2('67,7,x,59,61')) assert_eq(1202161486, part2('1789,37,47,1889')) print( f"timestamp = {part2('23,x,x,x,x,x,x,x,x,x,x,x,x,41,x,x,x,37,x,x,x,x,x,421,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,17,x,19,x,x,x,x,x,x,x,x,x,29,x,487,x,x,x,x,x,x,x,x,x,x,x,x,13')}" )
invalid_names.append(possible_name) for n in invalid_names: names[idx].remove(n) name_assignment = [] while len(names) > 0: name_assignment.extend( flatten(list(filter(lambda l: len(l) == 1, names)))) new_names = [] for n in names: new_n = [] for v in n: if v not in name_assignment: new_n.append(v) if len(new_n) > 0: new_names.append(new_n) names = new_names count = 1 for i, a in enumerate(name_assignment): if "departure " in a: print(f" '{a}' is my_ticket[{i}]={my_ticket[i]}") count *= my_ticket[i] return count assert_eq(71, part1("test")) print(f"sum of invalid = {part1('input')}") print(f"sum of departures = {part2('input')}")
curr = e nr_to_turns[e].append(i + 1) for i in range(len(numbers) + 1, idx + 1): if len(nr_to_turns[curr]) == 2: curr = nr_to_turns[curr][-1] - nr_to_turns[curr][-2] else: curr = 0 nr_to_turns[curr].append(i) if len(nr_to_turns[curr]) > 2: del nr_to_turns[curr][0] return curr assert_eq(436, part1(read_ints('0,3,6'))) assert_eq(1, part1(read_ints('1,3,2'))) assert_eq(10, part1(read_ints('2,1,3'))) assert_eq(27, part1(read_ints('1,2,3'))) assert_eq(78, part1(read_ints('2,3,1'))) assert_eq(438, part1(read_ints('3,2,1'))) assert_eq(1836, part1(read_ints('3,1,2'))) print(f"2020th nr = {part1(read_ints('15,12,0,14,3,1'))}") assert_eq(175594, part1(read_ints('0,3,6'), 30000000)) assert_eq(2578, part1(read_ints('1,3,2'), 30000000)) assert_eq(3544142, part1(read_ints('2,1,3'), 30000000)) assert_eq(261214, part1(read_ints('1,2,3'), 30000000)) assert_eq(6895259, part1(read_ints('2,3,1'), 30000000)) assert_eq(18, part1(read_ints('3,2,1'), 30000000)) assert_eq(362, part1(read_ints('3,1,2'), 30000000))
for parent in g.predecessors(my_bag): predecessors.add(parent) predecessors = predecessors.union(possible_holders_of_my_bag( g, parent)) return predecessors def count_bags_inside(g, my_bag="shiny gold"): def count_required_bags_inside(g, my_bag): count = 1 for child in g.successors(my_bag): count += g[my_bag][child]["weight"] * count_required_bags_inside( g, child) return count return count_required_bags_inside(g, my_bag) - 1 test_lines = read_lines('test') test_graph = parse_to_graph(test_lines) assert_eq(4, len(possible_holders_of_my_bag(test_graph))) assert_eq(32, count_bags_inside(test_graph)) lines = read_lines('input') graph = parse_to_graph(lines) parent_colors_cnt = len(possible_holders_of_my_bag(graph)) bags_in_my_bag = count_bags_inside(graph) print(f"Possible parent colors: {parent_colors_cnt}") print(f"Required bags: {count_bags_inside(graph)}")
if diff == 1: ones += 1 elif diff == 3: threes += 1 return ones * threes def count_combinations(adapters): adapters = list(reversed(sorted(adapters))) adapters.append(0) combinations_per_adapter = {} for idx in range(1, len(adapters)): possible_next_adapters = filter(lambda x: adapters[idx] >= x - 3, adapters[:idx]) count = sum( map(lambda x: combinations_per_adapter.get(x, 1), possible_next_adapters)) combinations_per_adapter[adapters[idx]] = count return combinations_per_adapter[min(adapters)] assert_eq(5 * 7, jolt_diffs(read_list_of_ints('test'))) assert_eq(22 * 10, jolt_diffs(read_list_of_ints('test2'))) print(f"jolt diff mult = {jolt_diffs(read_list_of_ints('input'))}") assert_eq(8, count_combinations(read_list_of_ints('test'))) assert_eq(19208, count_combinations(read_list_of_ints('test2'))) print( f"adapter combinations = {count_combinations(read_list_of_ints('input'))}")
if 36 - len(nr) <= i: addr[i] = nr[i - (36 - len(nr))] else: addr_copy = addr.copy() addr[i] = '1' addr_copy[i] = '0' additional_addr.append(addr_copy) addresses.extend(additional_addr) return list(map(lambda l: int("".join([str(i) for i in l]), 2), addresses)) def part2(lines: list): mask, numbers = "000000000000000000000000000000000000", {} for line in lines: if "mask = " in line: mask = line[7:] else: line = line.replace("mem[", "").replace("] = ", ",").split(",") for idx in convert2([int(x) for x in bin(int(line[0]))[2:]], mask): numbers[idx] = int(line[1]) return sum(numbers.values()) assert_eq(165, part1(read_lines('test'))) print(f"sum = {part1(read_lines('input'))}") assert_eq(208, part2(read_lines('test2'))) print(f"sum = {part2(read_lines('input'))}")
else: return wx, wy x, y, wx, wy = 0, 0, 10, 1 for instr in instructions: val = int(instr[1:]) if instr[0] == 'F': x += val * wx y += val * wy elif instr[0] == 'N': wy += val elif instr[0] == 'S': wy -= val elif instr[0] == 'W': wx -= val elif instr[0] == 'E': wx += val else: val = val // 90 val = 4 - val if instr[0] == 'L' else val wx, wy = rotate(val) return abs(x) + abs(y) assert_eq(25, sum_taxi_distance(read_lines('test'))) print(f"distance = {sum_taxi_distance(read_lines('input'))}") assert_eq(286, sum_taxi_distance2(read_lines('test'))) print(f"distance = {sum_taxi_distance2(read_lines('input'))}")
elif src[i][j] == 'L' and counter(src, i, j) == 0: cpy[i][j] = '#' else: cpy[i][j] = src[i][j] def count_taken(): return len(list(filter(lambda e: e == '#', flatten(cpy)))) transform() if src == cpy: return count_taken() else: return count_occupied(counter, cpy, src, round + 1, tolerance) def count_p1(m1): m2 = [line.copy() for line in m1] return count_occupied(count_neighbors_p1, m1, m2) def count_p2(m1): m2 = [line.copy() for line in m1] return count_occupied(count_neighbors_p2, m1, m2, tolerance=5) assert_eq(37, count_p1(read_matrix('test'))) print(f"occupied = {count_p1(read_matrix('input'))}") assert_eq(26, count_p2(read_matrix('test'))) print(f"occupied = {count_p2(read_matrix('input'))}")
from advent_utils import read_with_group_separator, flatten, assert_eq from functools import reduce def split_groups_into_letters(groups): def split_into_letters(group): return list(map(lambda i: list(i), group)) return [split_into_letters(group) for group in groups] def count_uniq_letters_in_groups(groups): return sum(map(lambda g: len(set(flatten(g))), groups)) def count_common_letters_in_groups(groups): def collect_common_letters_in_group(group): return reduce(lambda x, y: set(y).intersection(x), group) return sum(map(lambda g: len(collect_common_letters_in_group(g)), groups)) test = split_groups_into_letters(read_with_group_separator('test', '\n\n')) assert_eq(11, count_uniq_letters_in_groups(test)) assert_eq(6, count_common_letters_in_groups(test)) text = read_with_group_separator('input', '\n\n') groups_with_letters = split_groups_into_letters(text) print(f"uniq: {count_uniq_letters_in_groups(groups_with_letters)}") print(f"common: {count_common_letters_in_groups(groups_with_letters)}")