def part_1(raw: str): adapters = list(sorted(map(int, raw.splitlines()))) adapters = [0] + adapters + [max(adapters) + 3] differences = collections.defaultdict(int) for lower, higher in lib.window(adapters, 2): differences[higher - lower] += 1 return differences[1] * differences[3]
def count_contiguous_combinations(n: int): count = 0 for i in range(n): for combo in itertools.combinations(range(1, n), i): sequence = [0, *combo, n] differences = [hi - lo for lo, hi in lib.window(sequence, 2)] count += max(differences) <= 3 return count
def __init__(self, values: List[int]): self.min_val, self.max_val = min(values), max(values) self.nodes: Dict[int, Node] = {value: Node(value) for value in values} for prev, _next in lib.window(values): self.nodes[prev].next = self.nodes[_next] self.current_cup: Node = self.nodes[values[0]] self.nodes[values[-1]].next = self.current_cup
def fasta_to_kmer_counts(fasta_lines, k): kmer_counts = {} for line in fasta_lines: line_kmers = list(window(line, k)) for kmer in line_kmers: if kmer not in kmer_counts: kmer_counts[kmer] = 1 else: kmer_counts[kmer] += 1 return kmer_counts
def part_2(raw: str): adapters = [0] + list(sorted(map(int, raw.splitlines()))) one_differences = [0] for lower, higher in lib.window(adapters, 2): if higher - lower == 1: one_differences[-1] += 1 else: one_differences.append(0) one_differences = [num for num in one_differences if num > 0] individual_combinations = map(count_contiguous_combinations, one_differences) return lib.product(individual_combinations)
def part_2(raw: str): tiles = parse_input(raw) size = int(len(tiles)**0.5) shared_edges: EdgeMap = get_shared_edges(tiles) tlc = lib.first(get_corners(tiles)) top_left_edges = shared_edges[tlc].keys() while tlc.bottom() not in top_left_edges or tlc.right( ) not in top_left_edges: tlc = tlc.rotate() tile_grid: List[List[ImageTile]] = [[tlc]] for i in range(size - 1): current_tile = tile_grid[-1][0] key_tile = lib.first(current_tile.variations(), lambda v: v in shared_edges) downwards_tile = shared_edges[key_tile][current_tile.bottom()] variation = lib.first(downwards_tile.variations(), lambda v: v.top() == current_tile.bottom()) assert variation.top() == current_tile.bottom() tile_grid.append([variation]) for row in tile_grid: for i in range(size - 1): current_tile = row[-1] key_tile = lib.first(current_tile.variations(), lambda v: v in shared_edges) rightwards_tile = shared_edges[key_tile][current_tile.right()] variation = lib.first(rightwards_tile.variations(), lambda v: v.left() == current_tile.right()) assert current_tile.right() == variation.left() row.append(variation) for row in tile_grid: for t1, t2 in lib.window(row, 2): assert t1.right() == t2.left() for i in range(len(tile_grid)): column = [row[i] for row in tile_grid] for t1, t2 in lib.window(column, 2): assert t1.bottom() == t2.top() pixel_ids = [tile.tile_id for row in tile_grid for tile in row] assert len(set(pixel_ids)) == len(list(pixel_ids)) tile_size = len(tiles[0].pixels) pixels: List[List[bool]] = [] for row in tile_grid: for i in range(1, tile_size - 1): pixels.append([]) for tile in row: for pixel in tile.pixels[i][1:-1]: pixels[-1].append(pixel) mega_tile = ImageTile(1, tuple(tuple(row) for row in pixels)) return min(map(count_monsters, mega_tile.variations()))