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
|
||||
*.ex*
|
||||
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