import aoc from functools import reduce x = y = aim = 0 for cmd, n in aoc.read(): match cmd: case "forward": x += n y += aim * n case "down": aim += n case "up": aim -= n print("Part One", x * aim) print("Part Two", x * y) inp = aoc.read() def process(state, command): x, y, aim = state match command: case "forward", arg: return [x+arg, y+arg*aim, aim] case "up", arg: return [x, y, aim-arg] case "down", arg: return [x, y, aim+arg] case _: raise Exception(str(command))
from statistics import median, mean import aoc data = aoc.read("input.txt", sep=",", cast_as=int) m = median(data) fuel = sum(abs(x - m) for x in data) print(f"Part 1 - total fuel:", int(fuel)) def triangle_fuel(x, m): t = -1 if x < m else 1 return 0.5 * ((x - m) * (x - m + t)) min = None for i in range(len(data)): fuel = sum(triangle_fuel(x, i) for x in data) if min is None or min > fuel: min = fuel print(f"Part 2 - total fuel:", int(min))
import re from collections import namedtuple import aoc Point = namedtuple("Point", ["x", "y"]) numbers, *cards = aoc.read(path="input.txt", sep="\n\n", cast_as=str) numbers = [int(n) for n in numbers.split(",")] N = 5 # Bingo card length PATTERN_NUM = r"[0-9]+" def x(i, n=N): return i - ((i // n) * n) def y(i, n=N): return i // n class Card: ALL = set(range(N)) def __init__(self, data): ns = re.findall(PATTERN_NUM, data) self.data = {int(v): Point(x(i), y(i)) for i, v in enumerate(ns)} self.complete = False
from typing import List, Tuple import aoc data = aoc.read(path="input.txt", cast_as=str) N = len(data[0]) mapper = str.maketrans("01", "10") def dec(bin: str) -> int: return int(bin, 2) def most_common_bit(l: List[str]) -> str: n = len(l) ones = len([i for i in l if i == "1"]) return "1" if ones >= n / 2 else "0" def gamma(data): bits = "" for i in range(N): bit = most_common_bit([s[i] for s in data]) bits += bit return bits def epsilon(gamma):
import aoc l = aoc.read() def count(l): return sum(b > a for a, b in zip(l, l[1:])) print(count(l)) # Window of width 3 w = [sum(xs) for xs in zip(l, l[1:], l[2:])] print(count(w))
import aoc def pairwise(s): """Not on python 3.10.""" while True: try: a, b, *tail = s except ValueError: return yield a + b s = [b] + tail polymer, _, *rules = aoc.read("input.txt", cast_as=str, sep="\n") final = polymer[-1] # To add the last letter into the counts at the end rules = dict(pair.split(" -> ") for pair in rules) # Initialise poly = Counter(pairwise(polymer)) # Iterate simultaneously for _ in range(40): new = defaultdict(int) for pair in list(poly): n = poly[pair] insertion = rules[pair] new[pair[0] + insertion] += n new[insertion + pair[1]] += n poly = new
from aoc import Point, read from functools import reduce data = read("input.txt", cast_as=str, sep="\n") DELIM = data.index("") points = [Point(*map(int, p.split(","))) for p in data[:DELIM]] folds = [f.replace("fold along ", "") for f in data[(DELIM + 1):]] def make_fold(points, fold): axis, pos = fold.split("=") pos = int(pos) for p in points: px = (2 * pos - p.x) if (axis == "x") and (p.x > pos) else p.x py = (2 * pos - p.y) if (axis == "y") and (p.y > pos) else p.y yield Point(px, py) def printer(points): for y in range(10): ans = "" for x in range(60): ans += "#" if Point(x, y) in points else "." print(ans) printer(set(reduce(make_fold, folds, points)))
import aoc import more_itertools inp = aoc.read()[0] c1 = sum(a < b for a, b in zip(inp, inp[1:])) print("Part One", c1) c2 = sum(a < b for a, b in zip(inp, inp[3:])) c22 = sum( sum(inp[i:i + 3]) < sum(inp[i + 1:i + 4]) for i in range(0, len(inp) - 3)) c23 = sum(w[0] < w[-1] for w in more_itertools.windowed(inp, 4)) c24 = len([1 for a, b in zip(inp, inp[3:]) if a < b]) print("Part Two", c2, c22, c23, c24)
from itertools import chain, product from typing import List from aoc import Point, read data = read("input.txt", sep="\n\n", cast_as=str).pop() N = data.index("\n") data = data.replace("\n", "") ADJ = {-1, 0, 1} ADJ = [v for v in product(ADJ, ADJ) if v != (0, 0)] ENOUGH_ENERGY = 9 def print_octos(octopodes): Y = 1 for p, e in octopodes.items(): if p.y == Y: print("\n", end="") Y += 1 print(e if e <= ENOUGH_ENERGY else "x", end="") print("\n") def neighbours(p: Point) -> List[Point]: return [Point(p.x + dx, p.y + dy) for dx, dy in ADJ] def count_flashes(octopodes) -> int: return list(octopodes.values()).count(0)
from collections import defaultdict import aoc START = "start" END = "end" data = aoc.read("input.txt", sep="\n", cast_as=str) nodes = defaultdict(set) for edge in data: a, b = edge.split("-") nodes[a].add(b) if b != START else None nodes[b].add(a) if a != START else None nodes.pop(END) def traverse(): explore = [(p, {START, p}) for p in nodes[START]] paths = 0 while explore: head, visited = explore.pop() neighbours = nodes[head] for node in neighbours: if node == END: paths += 1 elif node.islower() and (node in visited): paths += 0 else: v = visited.copy()
assert eval(str(Node(in_).reduce())) == eval(out_) print("pass") # check([[[[[9, 8], 1], 2], 3], 4], "[[[[0,9],2],3],4]") # check([7, [6, [5, [4, [3, 2]]]]], "[7,[6,[5,[7,0]]]]") # check([[6, [5, [4, [3, 2]]]], 1], "[[6,[5,[7,0]]],3]") # check([[3, [2, [1, [7, 3]]]], [6, [5, [4, [3, 2]]]]], "[[3,[2,[8,0]]],[9,[5,[7,0]]]]") # check( # [[[[[4, 3], 4], 4], [7, [[8, 4], 9]]], [1, 1]], "[[[[0,7],4],[[7,8],[6,0]]],[8,1]]" # ) import aoc numbers = [Node(eval(n)) for n in aoc.read("input.txt", cast_as=str, sep="\n")] acc, *numbers = numbers for n in numbers: acc = acc + n acc.reduce() def magnitude(node): while True: if isinstance(node.l, int) and isinstance(node.r, int): return (3 * node.l) + (2 * node.r) if isinstance(node.l, Node): node.l = magnitude(node.l)