def parse(): for line in lines_from_day(2): words = line.split(" ") rdesc = words[0].split("-") a, b = int(rdesc[0]), int(rdesc[1]) char = words[1][0] string = words[2] yield (a, b, char, string)
from helper import lines_from_day from itertools import product # FBFBBFFRLR -> (0101100, 101) -> (44, 5) def read_seat(code): translation = str.maketrans("FBLR", "0101") tr = lambda s: int(s.translate(translation), base=2) row, col = tr(code[:7]), tr(code[7:]) return row, col def seat_id(p): r, c = p return 8 * r + c observed_seats = set(map(read_seat, lines_from_day(5))) print("part 1:", max(map(seat_id, observed_seats))) minrow, maxrow = min(observed_seats)[0], max(observed_seats)[0] all_possible_seats = set(product(range(minrow, maxrow), range(8))) # there is only one empty possible seat my_seat = list(all_possible_seats - observed_seats)[0] print("part 2:", seat_id(my_seat))
from helper import lines_from_day, buildlist input = buildlist(int, lines_from_day(10)) adapters = [0] + list(sorted(input)) + [max(input) + 3] differences = buildlist(lambda i: adapters[i + 1] - adapters[i], range(len(adapters) - 1)) print("part 1:", differences.count(3) * (differences.count(1))) # shameless (and awestruck'd) copy of Todd Ginsbergs beautiful Kotlin # solution at https://todd.ginsberg.com/post/advent-of-code/2020/day10/ def count_valid_arrangements(): paths = {0: 1} for a in adapters[1:]: paths[a] = sum(paths.get(a - d, 0) for d in [1, 2, 3]) return paths[max(adapters)] print("part 2:", count_valid_arrangements())
from itertools import combinations from helper import lines_from_day numbers = list(map(int, lines_from_day(1))) for (a, b) in combinations(numbers, 2): if (a + b) == 2020: print(f"{a} + {b} = {a+b}") print(f"{a} * {b} = {a*b}") for (a, b, c) in combinations(numbers, 3): if (a + b + c) == 2020: print(f"{a} + {b} + {c} = {a+b+c}") print(f"{a} * {b} * {c} = {a*b*c}")
from itertools import combinations, starmap from helper import lines_from_day from operator import add nums = list(map(int, lines_from_day(9))) def find_invalid_xmas_indices(nums): def not_valid_at(i): # i in [26, len(nums)) prec, n = nums[i-25:i], nums[i] return n not in starmap(add, combinations(prec, 2)) return list(filter(not_valid_at, range(26, len(nums)))) idxs = find_invalid_xmas_indices(nums) print("part 1:", idxs, list(map(nums.__getitem__, idxs))) def find_weakness(nums, m): for n in range(2, len(nums)): for i in range(len(nums)-n): span = nums[i:i+n] if sum(span) == m: return max(span) + min(span) print("part 2:", find_weakness(nums, nums[idxs[0]]))
def traverse(dx, dy): lines = list(lines_from_day(3)) h, w = len(lines), len(lines[0]) return list(lines[i * dy][i * dx % w] for i in range(h // dy))
from helper import lines_from_day from itertools import product import numpy as np tiles = np.array(list(list(line) for line in lines_from_day(11))) w, l = tiles.shape def count(ts, tt, i, j): marray = np.ma.array(ts) marray[i, j] = np.ma.masked region = marray[np.clip((i - 1), 0, w):np.clip((i + 2), 0, w), # 3x3 area np.clip((j - 1), 0, l):np.clip((j + 2), 0, l) # c. (i,j) ] return np.sum(region == tt) def next_from(ts, i, j): t = ts[i, j] return { "L": "#" if (count(ts, "#", i, j) == 0) else t, "#": "L" if (count(ts, "#", i, j) >= 4) else t }.get(t, t) # this method is _extremely_ inefficient. # # completes after 7 minutes on my laptop. # I guess expressibility comes at a cost # of effectivity; and my numpy-usage is
def parse(): for line in lines_from_day(8): instruction, operand = line.split(" ") yield (instruction, int(operand))
from helper import lines_from_day import re from functools import cache re_inner_bag = re.compile(r"(\d+) ([\w\s]+) bags?") def split(line): return line.split(" bags contain ") bdict = {(ps := split(line))[0]: {bag: int(n) for n, bag in re_inner_bag.findall(ps[1])} for line in lines_from_day(7)} @cache def search(s, bk): "True if bk contains s or if any of search(s, d) where d in bk" b = set(bdict[bk].keys()) return (s in b) or bool(b) and any(search(s, bn) for bn in b) n1 = sum(search("shiny gold", bag) for bag in bdict.keys()) print("part 1:", n1) def count_inner_bags(bk, *, _d=0): b = set(bdict[bk].keys())