Solve 2021 day 12-14
This commit is contained in:
56
2021/d12.py
Normal file
56
2021/d12.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from lib import get_data
|
||||
from lib import Grid2D
|
||||
from lib import ints
|
||||
from collections import deque
|
||||
from collections import defaultdict
|
||||
|
||||
data = get_data(__file__).strip()
|
||||
g = defaultdict(list)
|
||||
|
||||
|
||||
for line in data.splitlines():
|
||||
a, b = line.strip().split("-")
|
||||
g[a].append(b)
|
||||
g[b].append(a)
|
||||
|
||||
|
||||
def no_doubles(path):
|
||||
path = [p for p in path if p.islower()]
|
||||
return len(path) == len(set(path))
|
||||
|
||||
|
||||
for part in [1, 2]:
|
||||
start = ("start", ())
|
||||
visited = set()
|
||||
queue = deque([start])
|
||||
|
||||
total = 0
|
||||
while queue:
|
||||
vertex = queue.popleft()
|
||||
if vertex in visited:
|
||||
continue
|
||||
visited.add(vertex)
|
||||
|
||||
current, path = vertex
|
||||
|
||||
neighbors = []
|
||||
for neighbor in g[current]:
|
||||
if neighbor == "end":
|
||||
total += 1
|
||||
elif neighbor == "start":
|
||||
continue
|
||||
elif neighbor.islower():
|
||||
if neighbor not in path or (part == 2 and no_doubles(path)):
|
||||
new_path = tuple(list(path) + [neighbor])
|
||||
nb = (neighbor, new_path)
|
||||
if nb not in visited:
|
||||
queue.append(nb)
|
||||
elif neighbor.isupper():
|
||||
new_path = tuple(list(path) + [neighbor])
|
||||
nb = (neighbor, new_path)
|
||||
if nb not in visited:
|
||||
queue.append(nb)
|
||||
else:
|
||||
assert False
|
||||
|
||||
print(total)
|
||||
51
2021/d13.py
Normal file
51
2021/d13.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from lib import get_data
|
||||
from lib import ints
|
||||
|
||||
data = get_data(__file__).strip()
|
||||
|
||||
|
||||
def print_from_xy(xs):
|
||||
x_min = min(v[0] for v in xs)
|
||||
x_max = max(v[0] for v in xs)
|
||||
y_min = min(v[1] for v in xs)
|
||||
y_max = max(v[1] for v in xs)
|
||||
for y in range(y_min, y_max + 1):
|
||||
row = ""
|
||||
for x in range(x_min, x_max + 1):
|
||||
if (x, y) in xs:
|
||||
row += "#"
|
||||
else:
|
||||
row += " "
|
||||
print(row)
|
||||
|
||||
|
||||
p1, p2 = data.split("\n\n")
|
||||
xs = set([tuple(ints(line)) for line in p1.splitlines()])
|
||||
|
||||
folds = []
|
||||
for line in p2.splitlines():
|
||||
d = "x" if "x=" in line else "y"
|
||||
(n,) = ints(line)
|
||||
folds.append((d, n))
|
||||
|
||||
|
||||
first = None
|
||||
for d, n in folds:
|
||||
if d == "x":
|
||||
to_move = [(x, y) for (x, y) in xs if x > n]
|
||||
for x, y in to_move:
|
||||
xs.remove((x, y))
|
||||
new_x = n - (x - n)
|
||||
xs.add((new_x, y))
|
||||
elif d == "y":
|
||||
to_move = [(x, y) for (x, y) in xs if y > n]
|
||||
for x, y in to_move:
|
||||
xs.remove((x, y))
|
||||
new_y = n - (y - n)
|
||||
xs.add((x, new_y))
|
||||
else:
|
||||
assert False
|
||||
first = first or len(xs)
|
||||
|
||||
print(first)
|
||||
print_from_xy(xs)
|
||||
43
2021/d14.py
Normal file
43
2021/d14.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from lib import get_data
|
||||
from itertools import pairwise
|
||||
from collections import defaultdict
|
||||
|
||||
data = get_data(__file__)
|
||||
orig_t, p2 = data.split("\n\n")
|
||||
|
||||
pairs = {}
|
||||
for line in p2.splitlines():
|
||||
ls, rs = line.split(" -> ")
|
||||
assert ls not in pairs
|
||||
pairs[ls] = rs
|
||||
|
||||
for steps in [10, 40]:
|
||||
t = str(orig_t)
|
||||
start_letter = t[0]
|
||||
end_letter = t[-1]
|
||||
td = defaultdict(int)
|
||||
for a, b in pairwise(t):
|
||||
td[a + b] += 1
|
||||
|
||||
for _ in range(steps):
|
||||
ntd = defaultdict(int)
|
||||
for pair, count in td.items():
|
||||
if pair in pairs:
|
||||
a, b = pair
|
||||
c = pairs[pair]
|
||||
ntd[a + c] += count
|
||||
ntd[c + b] += count
|
||||
else:
|
||||
ntd[pair] += count
|
||||
td = ntd
|
||||
|
||||
counts = defaultdict(int)
|
||||
for (a, b), count in td.items():
|
||||
counts[a] += count
|
||||
counts[b] += count
|
||||
counts = {k: v // 2 for k, v in counts.items()}
|
||||
counts[start_letter] += 1
|
||||
counts[end_letter] += 1
|
||||
|
||||
r = max(counts.values()) - min(counts.values())
|
||||
print(r)
|
||||
Reference in New Issue
Block a user