Compare commits
2 commits
8b9e091bad
...
89e2c58a78
Author | SHA1 | Date | |
---|---|---|---|
89e2c58a78 | |||
14354c85b8 |
10 changed files with 476 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,6 @@
|
||||||
*.in
|
*.in
|
||||||
*.ex*
|
*.ex*
|
||||||
day??
|
day??
|
||||||
|
|
||||||
|
*.prof
|
||||||
|
*.lprof
|
||||||
|
|
25
day09.py
Normal file
25
day09.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import fileinput
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
def main():
|
||||||
|
part1 = 0
|
||||||
|
part2 = 0
|
||||||
|
|
||||||
|
for line in fileinput.input():
|
||||||
|
values = deque(int(t) for t in line.split())
|
||||||
|
|
||||||
|
stack = [values]
|
||||||
|
while any(values):
|
||||||
|
values = deque(values[i + 1] - values[i] for i in range(len(values) - 1))
|
||||||
|
stack.append(values)
|
||||||
|
|
||||||
|
for i in range(len(stack) - 1, 0, -1):
|
||||||
|
stack[i - 1].append(stack[i - 1][-1] + stack[i][-1])
|
||||||
|
stack[i - 1].appendleft(stack[i - 1][0] - stack[i][0])
|
||||||
|
|
||||||
|
part1 += stack[0][-1]
|
||||||
|
part2 += stack[0][0]
|
||||||
|
|
||||||
|
print(part1, part2)
|
||||||
|
|
||||||
|
main()
|
151
day10.py
Normal file
151
day10.py
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
from collections import deque
|
||||||
|
import fileinput
|
||||||
|
from pprint import pprint
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
map = []
|
||||||
|
|
||||||
|
(sx, sy) = (0, 0)
|
||||||
|
for (j, line) in enumerate(fileinput.input()):
|
||||||
|
map.append(list(line.strip()))
|
||||||
|
if (x := line.find("S")) != -1:
|
||||||
|
(sx, sy) = (x, j)
|
||||||
|
|
||||||
|
seen = set()
|
||||||
|
queue: deque[tuple[int, int, int]] = deque([(sx, sy, 0)])
|
||||||
|
distances = [[None] * len(map[0]) for _ in range(len(map))]
|
||||||
|
|
||||||
|
NS = "|"
|
||||||
|
WE = "-"
|
||||||
|
NE = "L"
|
||||||
|
NW = "J"
|
||||||
|
SW = "7"
|
||||||
|
SE = "F"
|
||||||
|
|
||||||
|
part1 = 0
|
||||||
|
while queue:
|
||||||
|
(x, y, l) = queue.popleft()
|
||||||
|
if (x, y) in seen:
|
||||||
|
continue
|
||||||
|
|
||||||
|
seen.add((x, y))
|
||||||
|
distances[y][x] = l
|
||||||
|
part1 = l
|
||||||
|
|
||||||
|
match map[y][x]:
|
||||||
|
case "S":
|
||||||
|
if map[y - 1][x] in "|7F":
|
||||||
|
queue.append((x, y - 1, l + 1))
|
||||||
|
if map[y + 1][x] in "|LJ":
|
||||||
|
queue.append((x, y + 1, l + 1))
|
||||||
|
if map[y][x - 1] in "-LF":
|
||||||
|
queue.append((x - 1, y, l + 1))
|
||||||
|
if map[y][x + 1] in "-J7":
|
||||||
|
queue.append((x + 1, y, l + 1))
|
||||||
|
case "|":
|
||||||
|
queue.append((x, y - 1, l + 1))
|
||||||
|
queue.append((x, y + 1, l + 1))
|
||||||
|
case "-":
|
||||||
|
queue.append((x - 1, y, l + 1))
|
||||||
|
queue.append((x + 1, y, l + 1))
|
||||||
|
case "L":
|
||||||
|
queue.append((x + 1, y, l + 1))
|
||||||
|
queue.append((x, y - 1, l + 1))
|
||||||
|
case "J":
|
||||||
|
queue.append((x - 1, y, l + 1))
|
||||||
|
queue.append((x, y - 1, l + 1))
|
||||||
|
case "7":
|
||||||
|
queue.append((x - 1, y, l + 1))
|
||||||
|
queue.append((x, y + 1, l + 1))
|
||||||
|
case "F":
|
||||||
|
queue.append((x + 1, y, l + 1))
|
||||||
|
queue.append((x, y + 1, l + 1))
|
||||||
|
|
||||||
|
part1 = 0
|
||||||
|
for l in distances:
|
||||||
|
part1 = max(part1, 0, *[i for i in l if i])
|
||||||
|
print(part1)
|
||||||
|
|
||||||
|
side = set()
|
||||||
|
for y in range(len(map)):
|
||||||
|
if map[y][0] == ".": side.add((0, y))
|
||||||
|
if map[y][-1] == ".": side.add((len(map[0]) - 1, y))
|
||||||
|
for x in range(len(map[0])):
|
||||||
|
if map[0][x] == ".": side.add((x, 0))
|
||||||
|
if map[-1][x] == ".": side.add((x, len(map) - 1))
|
||||||
|
|
||||||
|
mapp = []
|
||||||
|
for (x, row) in enumerate(map):
|
||||||
|
r = []
|
||||||
|
for (y, c) in enumerate(row):
|
||||||
|
match c:
|
||||||
|
case ".":
|
||||||
|
r.append(["..."]*3)
|
||||||
|
case "S":
|
||||||
|
r.append([".X.","XXX",".X."])
|
||||||
|
case "-":
|
||||||
|
r.append(["...","XXX","..."])
|
||||||
|
case "|":
|
||||||
|
r.append([".X.",".X.",".X."])
|
||||||
|
case "7":
|
||||||
|
r.append(["...","XX.",".X."])
|
||||||
|
case "F":
|
||||||
|
r.append(["...",".XX",".X."])
|
||||||
|
case "J":
|
||||||
|
r.append([".X.","XX.","..."])
|
||||||
|
case "L":
|
||||||
|
r.append([".X.",".XX","..."])
|
||||||
|
mapp.append(r)
|
||||||
|
|
||||||
|
bigmap = []
|
||||||
|
for row in mapp:
|
||||||
|
for y in range(3):
|
||||||
|
r = []
|
||||||
|
for col in row:
|
||||||
|
for x in range(3):
|
||||||
|
r.append(col[y][x])
|
||||||
|
bigmap.append(r)
|
||||||
|
print(r)
|
||||||
|
|
||||||
|
exterior = []
|
||||||
|
for y in range(len(bigmap)):
|
||||||
|
if bigmap[y][0] == ".":
|
||||||
|
exterior.append((0, y))
|
||||||
|
if bigmap[y][-1] == ".":
|
||||||
|
exterior.append((len(bigmap[0]) - 1, y))
|
||||||
|
|
||||||
|
|
||||||
|
for x in range(len(bigmap[0])):
|
||||||
|
if bigmap[0][x] == ".":
|
||||||
|
exterior.append((x, 0))
|
||||||
|
if bigmap[-1][x] == ".":
|
||||||
|
exterior.append((x, len(bigmap) - 1))
|
||||||
|
|
||||||
|
for (x, y) in exterior:
|
||||||
|
if y < 0 or y > len(bigmap) - 1:
|
||||||
|
continue
|
||||||
|
if x < 0 or x > len(bigmap[y]) - 1:
|
||||||
|
continue
|
||||||
|
if bigmap[y][x] != ".":
|
||||||
|
continue
|
||||||
|
|
||||||
|
bigmap[y][x] = "O"
|
||||||
|
|
||||||
|
exterior.append((x - 1, y))
|
||||||
|
exterior.append((x + 1, y))
|
||||||
|
exterior.append((x, y - 1))
|
||||||
|
exterior.append((x, y + 1))
|
||||||
|
|
||||||
|
for row in distances:
|
||||||
|
for c in row:
|
||||||
|
print("X" if c is not None else ".", end="")
|
||||||
|
print()
|
||||||
|
|
||||||
|
part2 = 0
|
||||||
|
for y in range(1, len(bigmap), 3):
|
||||||
|
for x in range(1, len(bigmap[y]), 3):
|
||||||
|
if bigmap[y][x] == "." or (distances[y // 3][x // 3] is None):
|
||||||
|
part2 += 1
|
||||||
|
map[y//3][x//3] = 'I'
|
||||||
|
|
||||||
|
print(part1, part2)
|
76
day11.py
Normal file
76
day11.py
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
import fileinput
|
||||||
|
import math
|
||||||
|
from pprint import pprint
|
||||||
|
from itertools import pairwise
|
||||||
|
|
||||||
|
def main():
|
||||||
|
(part1, part2) = (0, 0)
|
||||||
|
|
||||||
|
# parse
|
||||||
|
inp = fileinput.input()
|
||||||
|
coords_ = []
|
||||||
|
(w, h) = (0, 0)
|
||||||
|
for (y, row) in enumerate(inp):
|
||||||
|
for (x, c) in enumerate(row):
|
||||||
|
if c == "#":
|
||||||
|
coords_.append((x, y))
|
||||||
|
w = max(w, x)
|
||||||
|
h = max(h, y)
|
||||||
|
|
||||||
|
coords = coords_.copy()
|
||||||
|
|
||||||
|
(dx, dy) = (0, 0)
|
||||||
|
for j in range(h):
|
||||||
|
if not any(y_ == j + dy for (_, y_) in coords):
|
||||||
|
print(f"inserting row at y={j}")
|
||||||
|
for i in range(len(coords)):
|
||||||
|
(x_, y_) = coords[i]
|
||||||
|
if y_ > j + dy:
|
||||||
|
coords[i] = (x_, y_ + 1)
|
||||||
|
dy += 1
|
||||||
|
if not any(x_ == j + dx for (x_, _) in coords):
|
||||||
|
print(f"inserting column at x={j}")
|
||||||
|
for i in range(len(coords)):
|
||||||
|
(x_, y_) = coords[i]
|
||||||
|
if x_ > j + dx:
|
||||||
|
coords[i] = (x_ + 1, y_)
|
||||||
|
dx += 1
|
||||||
|
|
||||||
|
part1 = 0
|
||||||
|
for ai in range(len(coords)):
|
||||||
|
for bi in range(ai + 1, len(coords)):
|
||||||
|
(ax, ay) = coords[ai]
|
||||||
|
(bx, by) = coords[bi]
|
||||||
|
part1 += abs(ax - bx) + abs(ay - by)
|
||||||
|
|
||||||
|
coords = coords_.copy()
|
||||||
|
L = 1_000_000 - 1
|
||||||
|
|
||||||
|
(dx, dy) = (0, 0)
|
||||||
|
for j in range(h):
|
||||||
|
if not any(y_ == j + dy for (_, y_) in coords):
|
||||||
|
print(f"inserting rows at y={j}")
|
||||||
|
for i in range(len(coords)):
|
||||||
|
(x_, y_) = coords[i]
|
||||||
|
if y_ > j + dy:
|
||||||
|
coords[i] = (x_, y_ + L)
|
||||||
|
dy += L
|
||||||
|
if not any(x_ == j + dx for (x_, _) in coords):
|
||||||
|
print(f"inserting columns at x={j}")
|
||||||
|
for i in range(len(coords)):
|
||||||
|
(x_, y_) = coords[i]
|
||||||
|
if x_ > j + dx:
|
||||||
|
coords[i] = (x_ + L, y_)
|
||||||
|
dx += L
|
||||||
|
|
||||||
|
part2 = 0
|
||||||
|
for ai in range(len(coords)):
|
||||||
|
for bi in range(ai + 1, len(coords)):
|
||||||
|
(ax, ay) = coords[ai]
|
||||||
|
(bx, by) = coords[bi]
|
||||||
|
part2 += abs(ax - bx) + abs(ay - by)
|
||||||
|
|
||||||
|
print(part1, part2)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
34
day12.py
Normal file
34
day12.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import fileinput
|
||||||
|
import math
|
||||||
|
from pprint import pprint
|
||||||
|
from itertools import chain, combinations, count, groupby
|
||||||
|
import re
|
||||||
|
|
||||||
|
RE = re.compile(r"[#\?]")
|
||||||
|
|
||||||
|
def powerset(iterable):
|
||||||
|
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
|
||||||
|
s = list(iterable)
|
||||||
|
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
|
||||||
|
|
||||||
|
def main():
|
||||||
|
(part1, part2) = (0, 0)
|
||||||
|
|
||||||
|
inp = fileinput.input()
|
||||||
|
for line in inp:
|
||||||
|
(springs, groups) = line.split()
|
||||||
|
groups = [int(g) for g in groups.split(",")]
|
||||||
|
|
||||||
|
unknowns = [x for (x, c) in enumerate(springs) if c == "?"]
|
||||||
|
springs_ = springs.replace("?", ".")
|
||||||
|
for xs in powerset(unknowns):
|
||||||
|
h = "".join("#" if i in xs else c for (i, c) in enumerate(springs_))
|
||||||
|
match = [len(g) for g in RE.findall(h)]
|
||||||
|
if match == groups:
|
||||||
|
part1 += 1
|
||||||
|
|
||||||
|
|
||||||
|
print(part1, part2)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
47
day13.py
Normal file
47
day13.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import sys
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
# @profile
|
||||||
|
def main():
|
||||||
|
with open(sys.argv[1]) as f:
|
||||||
|
inp = [
|
||||||
|
[[c == "#" for c in line] for line in field.split("\n")]
|
||||||
|
for field in f.read().strip().split("\n\n")
|
||||||
|
]
|
||||||
|
|
||||||
|
(part1, part2) = (0, 0)
|
||||||
|
|
||||||
|
for field in inp:
|
||||||
|
field = np.array(field)
|
||||||
|
(h, w) = field.shape
|
||||||
|
|
||||||
|
(x1, y1, x2, y2) = (0, 0, 0, 0)
|
||||||
|
for x in range(1, w):
|
||||||
|
w2 = min(x, w - x)
|
||||||
|
left = field[:, (x - w2) : x]
|
||||||
|
right = field[:, x : (x + w2)][:, ::-1]
|
||||||
|
mismatches = (left != right).sum()
|
||||||
|
if not x2 and mismatches == 1:
|
||||||
|
x2 = x
|
||||||
|
elif not x1 and mismatches == 0:
|
||||||
|
x1 = x
|
||||||
|
|
||||||
|
if not x1 or not x2:
|
||||||
|
for y in range(1, h):
|
||||||
|
h2 = min(y, h - y)
|
||||||
|
left = field[(y - h2) : y]
|
||||||
|
right = field[y : (y + h2)][::-1]
|
||||||
|
mismatches = (left != right).sum()
|
||||||
|
if not y2 and mismatches == 1:
|
||||||
|
y2 = y
|
||||||
|
elif not y1 and mismatches == 0:
|
||||||
|
y1 = y
|
||||||
|
|
||||||
|
part1 += x1 + y1 * 100
|
||||||
|
part2 += x2 + y2 * 100
|
||||||
|
|
||||||
|
print(part1, part2)
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
47
day15.py
Normal file
47
day15.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
def hash(s):
|
||||||
|
v = 0
|
||||||
|
for c in s:
|
||||||
|
if c == ",":
|
||||||
|
continue
|
||||||
|
v += ord(c)
|
||||||
|
v *= 17
|
||||||
|
v %= 256
|
||||||
|
return v
|
||||||
|
|
||||||
|
with open(sys.argv[1]) as f:
|
||||||
|
s = f.read().strip()
|
||||||
|
|
||||||
|
boxes = defaultdict(list)
|
||||||
|
|
||||||
|
part1 = 0
|
||||||
|
for s_ in s.split(","):
|
||||||
|
part1 += hash(s_)
|
||||||
|
|
||||||
|
if s_[-1] == "-":
|
||||||
|
label = s_[:-1]
|
||||||
|
h = hash(label)
|
||||||
|
for i in range(len(boxes[h])):
|
||||||
|
if boxes[h][i][0] == label:
|
||||||
|
del boxes[h][i]
|
||||||
|
break
|
||||||
|
elif s_[-2] == "=":
|
||||||
|
label = s_[:-2]
|
||||||
|
focal = int(s_[-1])
|
||||||
|
h = hash(label)
|
||||||
|
for i in range(len(boxes[h])):
|
||||||
|
if boxes[h][i][0] == label:
|
||||||
|
boxes[h][i] = (label, focal)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
boxes[h].append((label, focal))
|
||||||
|
|
||||||
|
part2 = 0
|
||||||
|
for (box_i, box) in boxes.items():
|
||||||
|
for (slot, (_, focal)) in enumerate(box):
|
||||||
|
part2 += (box_i + 1) * (slot + 1) * focal
|
||||||
|
|
||||||
|
print(part1, part2)
|
76
day16.py
Normal file
76
day16.py
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def simulate(map, entry):
|
||||||
|
seen = set()
|
||||||
|
energised = set()
|
||||||
|
stack: list[tuple[tuple[int, int], tuple[int, int]]] = [entry]
|
||||||
|
while stack:
|
||||||
|
entry = stack.pop()
|
||||||
|
if entry in seen:
|
||||||
|
continue
|
||||||
|
seen.add(entry)
|
||||||
|
|
||||||
|
((x, y), (dx, dy)) = entry
|
||||||
|
if not (0 <= y < len(map)) or not (0 <= x < len(map[y])):
|
||||||
|
continue
|
||||||
|
|
||||||
|
energised.add((x, y))
|
||||||
|
|
||||||
|
match map[y][x]:
|
||||||
|
case ".":
|
||||||
|
stack.append(((x + dx, y + dy), (dx, dy)))
|
||||||
|
case "-" if dy == 0:
|
||||||
|
stack.append(((x + dx, y + dy), (dx, dy)))
|
||||||
|
case "-":
|
||||||
|
stack.append(((x - 1, y), (-1, 0)))
|
||||||
|
stack.append(((x + 1, y), (1, 0)))
|
||||||
|
case "|" if dx == 0:
|
||||||
|
stack.append(((x + dx, y + dy), (dx, dy)))
|
||||||
|
case "|":
|
||||||
|
stack.append(((x, y - 1), (0, -1)))
|
||||||
|
stack.append(((x, y + 1), (0, 1)))
|
||||||
|
case "/" if (dx, dy) == (1, 0):
|
||||||
|
stack.append(((x, y - 1), (0, -1)))
|
||||||
|
case "/" if (dx, dy) == (-1, 0):
|
||||||
|
stack.append(((x, y + 1), (0, 1)))
|
||||||
|
case "/" if (dx, dy) == (0, 1):
|
||||||
|
stack.append(((x - 1, y), (-1, 0)))
|
||||||
|
case "/" if (dx, dy) == (0, -1):
|
||||||
|
stack.append(((x + 1, y), (1, 0)))
|
||||||
|
case "\\" if (dx, dy) == (1, 0):
|
||||||
|
stack.append(((x, y + 1), (0, 1)))
|
||||||
|
case "\\" if (dx, dy) == (-1, 0):
|
||||||
|
stack.append(((x, y - 1), (0, -1)))
|
||||||
|
case "\\" if (dx, dy) == (0, 1):
|
||||||
|
stack.append(((x + 1, y), (1, 0)))
|
||||||
|
case "\\" if (dx, dy) == (0, -1):
|
||||||
|
stack.append(((x - 1, y), (-1, 0)))
|
||||||
|
|
||||||
|
return len(energised)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open(sys.argv[1]) as f:
|
||||||
|
map = [list(l) for l in f.read().strip().splitlines()]
|
||||||
|
|
||||||
|
part1 = simulate(map, ((0, 0), (1, 0)))
|
||||||
|
|
||||||
|
part2 = 0
|
||||||
|
for y in range(len(map)):
|
||||||
|
w = len(map[y])
|
||||||
|
|
||||||
|
xp = simulate(map, ((0, y), (1, 0)))
|
||||||
|
xm = simulate(map, ((w - 1, y), (-1, 0)))
|
||||||
|
part2 = max(part2, xp, xm)
|
||||||
|
|
||||||
|
for x in range(len(map)):
|
||||||
|
h = len(map)
|
||||||
|
|
||||||
|
yp = simulate(map, ((x, 0), (0, 1)))
|
||||||
|
ym = simulate(map, ((x, h - 1), (0, -1)))
|
||||||
|
part2 = max(part2, yp, ym)
|
||||||
|
|
||||||
|
print(part1, part2)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
2
empty.py
Normal file
2
empty.py
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
import fileinput
|
||||||
|
list(fileinput.input())
|
15
template.py
Normal file
15
template.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import fileinput
|
||||||
|
import math
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
def main():
|
||||||
|
(part1, part2) = (0, 0)
|
||||||
|
|
||||||
|
inp = fileinput.input()
|
||||||
|
for line in inp:
|
||||||
|
pass
|
||||||
|
|
||||||
|
print(part1, part2)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in a new issue