aoc
/
2022
1
0
Fork 0

whole bunch of days

This commit is contained in:
Sijmen 2022-12-24 15:59:27 +01:00
parent e1a4d88b80
commit 8ffef89b6f
Signed by: vijfhoek
GPG Key ID: DAF7821E067D9C48
13 changed files with 446 additions and 55 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

43
day07.py Normal file
View File

@ -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))

45
day08.py Normal file
View File

@ -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))

55
day09.py Normal file
View File

@ -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()

33
day10.py Normal file
View File

@ -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]))

76
day11.py Normal file
View File

@ -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:]))

60
day12.py Normal file
View File

@ -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)

44
day13.py Normal file
View File

@ -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()