From 8ffef89b6f535b97aa6e5393cd419bd0da109b0a Mon Sep 17 00:00:00 2001 From: Sijmen Date: Sat, 24 Dec 2022 15:59:27 +0100 Subject: [PATCH] whole bunch of days --- day01.py | 14 ++++++++--- day02.py | 20 +++++++++------ day03.py | 36 +++++++++++++++------------ day04.py | 21 ++++++++++------ day05.py | 43 +++++++++++++++++++------------- day06.py | 11 +++++--- day07.py | 43 ++++++++++++++++++++++++++++++++ day08.py | 45 +++++++++++++++++++++++++++++++++ day09.py | 55 ++++++++++++++++++++++++++++++++++++++++ day10.py | 33 ++++++++++++++++++++++++ day11.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ day12.py | 60 ++++++++++++++++++++++++++++++++++++++++++++ day13.py | 44 ++++++++++++++++++++++++++++++++ 13 files changed, 446 insertions(+), 55 deletions(-) create mode 100644 day07.py create mode 100644 day08.py create mode 100644 day09.py create mode 100644 day10.py create mode 100644 day11.py create mode 100644 day12.py create mode 100644 day13.py diff --git a/day01.py b/day01.py index 00e64df..b9ab286 100644 --- a/day01.py +++ b/day01.py @@ -1,7 +1,13 @@ import sys -input = sys.stdin.read().strip().split("\n\n") -elves = sorted(sum(int(i) for i in elf.split("\n")) for elf in input) -print("Part 1:", elves[-1]) -print("Part 2:", sum(elves[-3:])) +def main(): + input = sys.stdin.read().strip().split("\n\n") + elves = sorted(sum(int(i) for i in elf.split("\n")) for elf in input) + + print("Part 1:", elves[-1]) + print("Part 2:", sum(elves[-3:])) + + +if __name__ == "__main__": + main() diff --git a/day02.py b/day02.py index ca7927f..1733669 100644 --- a/day02.py +++ b/day02.py @@ -1,12 +1,18 @@ import fileinput -part1, part2 = 0, 0 -for line in fileinput.input(mode='rb'): - theirs = line[0] - ord('A') - ours = line[2] - ord('X') +def main(): + part1, part2 = 0, 0 - part1 += ours + (ours - theirs + 1) % 3 * 3 + 1 - part2 += ours * 3 + (theirs + ours - 1) % 3 + 1 + for line in fileinput.input(mode="rb"): + theirs = line[0] - ord("A") + ours = line[2] - ord("X") -print(part1, part2) + part1 += ours + (ours - theirs + 1) % 3 * 3 + 1 + part2 += ours * 3 + (theirs + ours - 1) % 3 + 1 + + print(part1, part2) + + +if __name__ == "__main__": + main() diff --git a/day03.py b/day03.py index d821be8..c03e48c 100644 --- a/day03.py +++ b/day03.py @@ -1,8 +1,5 @@ import fileinput -input = [s.strip() for s in fileinput.input()] -part1, part2 = 0, 0 - def prio(x): if x.islower(): @@ -11,18 +8,25 @@ def prio(x): return ord(x) - ord("A") + 27 -for line in input: - first = set(line[: len(line) // 2]) - second = set(line[len(line) // 2 :]) - both = (first & second).pop() - part1 += prio(both) +def main(): + input = [s.strip() for s in fileinput.input()] + part1, part2 = 0, 0 + + for line in input: + first = set(line[: len(line) // 2]) + second = set(line[len(line) // 2 :]) + both = (first & second).pop() + part1 += prio(both) + + for i in range(0, len(input), 3): + x = set(input[i]) + y = set(input[i + 1]) + z = set(input[i + 2]) + overlap = (x & y & z).pop() + part2 += prio(overlap) + + print(part1, part2) -for i in range(0, len(input), 3): - x = set(input[i]) - y = set(input[i + 1]) - z = set(input[i + 2]) - overlap = (x & y & z).pop() - part2 += prio(overlap) - -print(part1, part2) +if __name__ == "__main__": + main() diff --git a/day04.py b/day04.py index 1bd8062..180510e 100644 --- a/day04.py +++ b/day04.py @@ -1,14 +1,19 @@ import fileinput -part1, part2 = 0, 0 -for line in fileinput.input(): - a, b = line.split(",", 1) - a1, a2 = [int(x) for x in a.split("-", 1)] - b1, b2 = [int(x) for x in b.split("-", 1)] +def main(): + part1, part2 = 0, 0 - part1 += (a1 >= b1 and b2 >= a2) or (b1 >= a1 and a2 >= b2) - part2 += a1 <= b2 and a2 >= b1 + for line in fileinput.input(): + a, b = line.split(",", 1) + a1, a2 = [int(x) for x in a.split("-", 1)] + b1, b2 = [int(x) for x in b.split("-", 1)] + + part1 += (a1 >= b1 and b2 >= a2) or (b1 >= a1 and a2 >= b2) + part2 += a1 <= b2 and a2 >= b1 + + print(part1, part2) -print(part1, part2) +if __name__ == "__main__": + main() diff --git a/day05.py b/day05.py index 4e9c3fe..e2582b5 100644 --- a/day05.py +++ b/day05.py @@ -1,26 +1,35 @@ import sys import numpy -inp_stacks, inp_moves = (x.split("\n") for x in sys.stdin.read().split("\n\n", 1)) -rows = (line[1::4] for line in inp_stacks[::-1] if "[" in line) -stacks = [numpy.array([ord(c) for c in x if c != ' '], dtype=numpy.int8) for x in zip(*rows)] -stacks1 = numpy.array(stacks) -stacks2 = numpy.ndarray.copy(stacks1) +def main(): + inp_stacks, inp_moves = (x.split("\n") for x in sys.stdin.read().split("\n\n", 1)) -for i, line in enumerate(inp_moves): - if i % 10000 == 0: - print(i, len(inp_moves), end="\r") - if not line: - continue + rows = (line[1::4] for line in inp_stacks[::-1] if "[" in line) + stacks = [ + numpy.array([ord(c) for c in x if c != " "], dtype=numpy.int8) + for x in zip(*rows) + ] + stacks1 = numpy.array(stacks) + stacks2 = numpy.ndarray.copy(stacks1) - _, a, _, b, _, c = line.split() - n, f, t = int(a), int(b) - 1, int(c) - 1 + for i, line in enumerate(inp_moves): + if i % 10000 == 0: + print(i, len(inp_moves), end="\r") + if not line: + continue - stacks1[t] = numpy.concatenate((stacks1[t], stacks1[f][-n:][::-1])) - stacks1[f] = stacks1[f][:-n] + _, a, _, b, _, c = line.split() + n, f, t = int(a), int(b) - 1, int(c) - 1 - stacks2[t] = numpy.concatenate((stacks2[t], stacks2[f][-n:])) - stacks2[f] = stacks2[f][:-n] + stacks1[t] = numpy.concatenate((stacks1[t], stacks1[f][-n:][::-1])) + stacks1[f] = stacks1[f][:-n] -print("".join(chr(s[-1]) for s in stacks1), "".join(chr(s[-1]) for s in stacks2)) + stacks2[t] = numpy.concatenate((stacks2[t], stacks2[f][-n:])) + stacks2[f] = stacks2[f][:-n] + + print("".join(chr(s[-1]) for s in stacks1), "".join(chr(s[-1]) for s in stacks2)) + + +if __name__ == "__main__": + main() diff --git a/day06.py b/day06.py index 3f873d0..37fb0bd 100644 --- a/day06.py +++ b/day06.py @@ -1,3 +1,8 @@ -inp = input().strip() -print(next(i + 4 for i in range(len(inp)) if len(set(inp[i : i + 4])) == 4)) -print(next(i + 14 for i in range(len(inp)) if len(set(inp[i : i + 14])) == 14)) +def main(): + inp = input().strip() + print(next(i + 4 for i in range(len(inp)) if len(set(inp[i : i + 4])) == 4)) + print(next(i + 14 for i in range(len(inp)) if len(set(inp[i : i + 14])) == 14)) + + +if __name__ == "__main__": + main() diff --git a/day07.py b/day07.py new file mode 100644 index 0000000..cb208d9 --- /dev/null +++ b/day07.py @@ -0,0 +1,43 @@ +import fileinput +from collections import defaultdict +from pprint import pprint + +cwd: list[str] = [] +folders: defaultdict[tuple[str, ...], int] = defaultdict(int) +subdirs: defaultdict[tuple[str, ...], list[str]] = defaultdict(list) + +for line in fileinput.input(): + s = line.split() + + if s[0] == "$": + if s[1] == "cd": + if s[2] == "..": + cwd.pop() + elif s[2] == "/": + cwd.clear() + else: + cwd.append(s[2]) + else: + if s[0].isdigit(): + folders[tuple(cwd)] += int(s[0]) + elif s[0] == "dir": + subdirs[tuple(cwd)].append(s[1]) + + +def recur(path: tuple[str, ...]) -> int: + # size = folders[path] + for subdir in subdirs[path]: + folders[path] += recur(path + (subdir,)) + return folders[path] + + +recur(()) +pprint(folders) + +part1 = sum(x for x in folders.values() if x <= 100_000) +print(part1) + +used = folders[()] +free = 70_000_000 - used +need_freed = 30_000_000 - free +print(min(x for x in folders.values() if x > 30_000_000 - free)) diff --git a/day08.py b/day08.py new file mode 100644 index 0000000..6aeee9a --- /dev/null +++ b/day08.py @@ -0,0 +1,45 @@ +import fileinput +from pprint import pprint + +inp = [[int(y) for y in x.strip()] for x in fileinput.input()] +inp_ = list(zip(*inp)) + +part1 = 0 + +for y in range(1, len(inp) - 1): + for x in range(1, len(inp[0]) - 1): + x_min_max = max(inp_[x][:y]) + y_min_max = max(inp[y][:x]) + x_max_max = max(inp_[x][y + 1 :]) + y_max_max = max(inp[y][x + 1 :]) + n = inp[y][x] + if n > x_min_max or n > y_min_max or n > x_max_max or n > y_max_max: + part1 += 1 + +part1 += (len(inp) - 1) * 4 + + +def viewing_dist(x: int, y: int, dx: int, dy: int) -> int: + dist = 0 + n = inp[y][x] + m = 0 + while n > m: + x += dx + y += dy + if x < 0 or y < 0 or y >= len(inp) or x >= len(inp[0]): + break + dist += 1 + m = inp[y][x] + return dist + + +scores = [] +for y in range(1, len(inp) - 1): + for x in range(1, len(inp[0]) - 1): + a = viewing_dist(x, y, 0, -1) + b = viewing_dist(x, y, -1, 0) + c = viewing_dist(x, y, 1, 0) + d = viewing_dist(x, y, 0, 1) + scores.append(a * b * c * d) + +print(part1, max(scores)) diff --git a/day09.py b/day09.py new file mode 100644 index 0000000..0d2a6c6 --- /dev/null +++ b/day09.py @@ -0,0 +1,55 @@ +import fileinput + +tx, ty, hx, hy = 0, 0, 0, 0 + +tail_positions = set() + +for line in fileinput.input(): + dir_, steps = line.split() + + dx, dy = 0, 0 + match dir_: + case "U": + dx, dy = 0, 1 + case "D": + dx, dy = 0, -1 + case "L": + dx, dy = -1, 0 + case "R": + dx, dy = 1, 0 + case _: + assert False + + for _ in range(int(steps)): + hx_, hy_ = hx, hy + hx += dx + hy += dy + if abs(tx - hx) > 1 or abs(ty - hy) > 1: + tx = hx_ + ty = hy_ + # for y in range(6, -1, -1): + # for x in range(6): + # if (x, y) == (hx, hy): + # print("H", end="") + # elif (x, y) == (tx, ty): + # print("T", end="") + # elif (x, y) == (0, 0): + # print("s", end="") + # else: + # print(".", end="") + # print() + # print() + tail_positions.add((tx, ty)) + print("========") + +print(len(tail_positions)) + +for y in range(10, -1, -1): + for x in range(20): + if (x, y) == (0, 0): + print("s", end="") + elif (x, y) in tail_positions: + print("#", end="") + else: + print(".", end="") + print() diff --git a/day10.py b/day10.py new file mode 100644 index 0000000..b7b1432 --- /dev/null +++ b/day10.py @@ -0,0 +1,33 @@ +import fileinput + +reg_x = 1 +cyc = 0 + +DURATIONS = {"noop": 1, "addx": 2} + +part1 = 0 +screen = [0] * 240 + +for line in fileinput.input(): + mnem, *args = line.strip().split() + d = 0 + + for _ in range(DURATIONS[mnem]): + cyc += 1 + if (cyc - 20) % 40 == 0: + part1 += cyc * reg_x + + c = (cyc - 1) % 40 + 1 + if reg_x == c or reg_x + 1 == c or reg_x + 2 == c: + screen[cyc - 1] = reg_x + + match mnem: + case "noop": + pass + + case "addx": + reg_x += int(args[0]) + +print(part1) +for i in range(0, 240, 40): + print("".join("#" if h else " " for h in screen[i : i + 40])) diff --git a/day11.py b/day11.py new file mode 100644 index 0000000..b1b0cdf --- /dev/null +++ b/day11.py @@ -0,0 +1,76 @@ +import sys +from pprint import pprint +from dataclasses import dataclass +from functools import reduce +from typing import List +import operator + + +@dataclass +class Monke: + operation: str + param: str + divisible_by: int + if_true: int + if_false: int + + +inputs = [l.split("\n") for l in sys.stdin.read().split("\n\n")] +monkeys: List[Monke] = [] + +items = [] +inspections = [] +visited = [] + +for monkey in inputs: + items.append(tuple(int(x) for x in monkey[1][18:].split(", "))) + inspections.append(0) + visited.append({}) + + op, param = monkey[2].split()[4:] + divisible_by = int(monkey[3].split()[-1]) + if_true = int(monkey[4].split()[-1]) + if_false = int(monkey[5].split()[-1]) + + monkeys.append(Monke(op, param, divisible_by, if_true, if_false)) + + +def do_round(): + for m, monke in enumerate(monkeys): + # print("Monke", m, monke.items) + for item in items[m]: + inspections[m] += 1 + + # print(" W :=", item) + + param = item if monke.param == "old" else int(monke.param) + if monke.operation == "*": + item *= param + # print(" W *", param, "=", item) + elif monke.operation == "+": + item += param + # print(" W +", param, "=", item) + else: + assert False + + item //= 3 + # print(" W / 3 =", item) + + divisible = item % monke.divisible_by == 0 + # print(" W %", monke.divisible_by, "== 0 =", divisible) + + target = monke.if_true if divisible else monke.if_false + # print(" Thrown to", target) + items[target] = (*items[target], item) + + items[m] = () + + +for i in range(20): + do_round() +print(reduce(operator.mul, sorted(inspections)[-2:])) + +# for i in range(20, 10_000): +# if i % 100 == 0: print(i) +# do_round() +print(reduce(operator.mul, sorted(inspections)[-2:])) diff --git a/day12.py b/day12.py new file mode 100644 index 0000000..b92da2a --- /dev/null +++ b/day12.py @@ -0,0 +1,60 @@ +import fileinput +from collections import deque + +map = [] +start_pos = None +end_pos = None + +for y, row in enumerate(fileinput.input(mode="rb")): + row = row.strip() + if not row: + continue + + r = [] + for x, col in enumerate(row): + match col: + case 83: + start_pos = (x, y) + r.append(0) + case 69: + end_pos = (x, y) + r.append(25) + case _: + r.append(col - 97) + map.append(r) + +assert start_pos is not None +assert end_pos is not None + +part1, part2 = None, None + +trace: tuple[tuple[int, int], ...] = () +stack = deque([(0, end_pos, trace)]) +visited = set() +while stack: + h_, (x, y), trace = stack.popleft() + if x < 0 or x >= len(map[0]) or y < 0 or y >= len(map) or (x, y) in visited: + continue + + h = map[y][x] + if h - h_ < -1: + continue + + if part1 is None and (x, y) == start_pos: + part1 = len(trace) + if part2 is None and h == 0: + part2 = len(trace) + if part1 is not None and part2 is not None: + break + + visited.add((x, y)) + + trace = trace + ((x, y, h),) + stack.append((h, (x - 1, y + 0), trace)) + stack.append((h, (x + 1, y + 0), trace)) + stack.append((h, (x + 0, y - 1), trace)) + stack.append((h, (x + 0, y + 1), trace)) +else: + assert False + +print(part1, part2) diff --git a/day13.py b/day13.py new file mode 100644 index 0000000..d4bc14f --- /dev/null +++ b/day13.py @@ -0,0 +1,44 @@ +import fileinput +import json +from functools import cmp_to_key +from typing import Any + + +def main() -> None: + pairs = [] + pair: list[list[Any]] = [] + packets = [[[2]], [[6]]] + + for line in fileinput.input(): + if not line.strip(): + pairs.append(pair) + pair = [] + else: + obj = json.loads(line) + pair.append(obj) + packets.append(obj) + + pairs.append(pair) + + def cmp(xs: list[Any] | int, ys: list[Any] | int) -> int: + if isinstance(xs, int) and isinstance(ys, int): + return (xs > ys) - (xs < ys) + + if isinstance(xs, int): + xs = [xs] + if isinstance(ys, int): + ys = [ys] + + for x, y in zip(xs, ys): + if result := cmp(x, y): + return result + + return (len(xs) > len(ys)) - (len(xs) < len(ys)) + + print(sum(i + 1 for i, (xs, ys) in enumerate(pairs) if cmp(xs, ys) == -1)) + + packets.sort(key=cmp_to_key(cmp)) + print((packets.index([[2]]) + 1) * (packets.index([[6]]) + 1)) + + +main()