Solve 2025 day 9 pt 2

Flood fill was too expensive, so I tried solving it with ray casting.

I believe it is the 2nd or 3rd time during 11 runs where it has been
requested.

wip

wip
This commit is contained in:
Anders Englöf Ytterström 2025-12-09 19:27:43 +01:00 committed by Anders Englöf Ytterström
parent ae676bf112
commit b8409db06c
2 changed files with 71 additions and 49 deletions

View file

@ -1,5 +1,6 @@
import re
from math import inf
from PIL import Image
# Directions/Adjacents for 2D matrices, in the order UP, RIGHT, DOWN, LEFT
D = [
@ -90,15 +91,47 @@ def vdbg(seen, mask=("#", "."), M=None):
r = max(r, x)
b = max(b, y)
l = min(l, x)
H = b - t + 1
W = r - l + 1
osr = t
osc = l
H = b + 1
W = r + 1
osr = 0 #t
osc = 0 #l
C, Z = mask
def _m(r, c):
return M[r][c] if M else Z
O = []
for r in range(H):
print("".join([C if (r + osr, c + osc) in seen else _m(r, c) for c in range(W)]))
O.append("".join([C if (r + osr, c + osc) in seen else _m(r, c) for c in range(W)]))
print("\n".join(O))
def svg(seen):
"""Print-debug visited positions of a matrix"""
t = inf
l = inf
b = 0
r = 0
rects = []
for y, x in seen:
t = min(t, y)
r = max(r, x)
b = max(b, y)
l = min(l, x)
H = b - t + 1
W = r - l + 1
print(t, r, b, l)
im = Image.new(mode="RGB", size=(W,H), color=(255,255,255))
for y, x in seen:
im.putpixel((x-l, y-t), (0, 0, 0, 255))
im.save("aoc.png")
for y, x in seen:
rects.append(f"<rect x='{x-l}' y='{y-t}' width='1' fill='black' stroke='black' stroke-width='10' height='1' />")
with open("svg.svg", "w") as f:
f.write(f"""
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" width="{W}" height="{H}">
{"".join(rects)}
</svg>
""".strip())
def vvdbg(seen, h, w):

View file

@ -1,3 +1,4 @@
from math import inf
from itertools import combinations
from output import ints
@ -7,13 +8,21 @@ def solve(data):
p1 = 0
p2 = 0
A = [tuple(ints(pos)) for pos in data.splitlines()]
T = inf
R = 0
B = 0
L = inf
for r, c in A:
T = min(r, T)
R = max(c, R)
B = max(r, B)
L = min(c, L)
S = A[0]
V = set()
B = set()
W = set()
while True:
V.add(S)
W.add(S)
y, x = S
he = [(r, c) for r, c in A if r == y and (r, c) not in V]
ve = [(r, c) for r, c in A if c == x and (r, c) not in V]
@ -28,61 +37,41 @@ def solve(data):
y2, x2 = E
for r in range(min(y, y2), max(y, y2) + 1):
for c in range(min(x, x2), max(x, x2) + 1):
B.add((r, c))
W.add((r, c))
if E == A[0]:
break
S = E
# find out a better start for Flood fill by visualizing
Y = 1841
X = 53478
# or, find a way to floodfill without BFS
# end
y, x = Y, X
Q = [(y, x)]
V = V | B
while Q:
yx = Q.pop()
if yx in V:
continue
V.add(yx)
y, x = yx
for dy, dx in D:
Q.append((dy + y, dx + x))
V = V | W
for a, b in combinations(A, r=2):
y1, x1 = a
y2, x2 = b
x = abs(x1 - x2) + 1
y = abs(y1 - y2) + 1
p1 = max(p1, x * y)
if (
len(
set(
[
(min(y1, y2), min(x1, x2)),
(min(y1, y2), max(x1, x2)),
(max(y1, y2), min(x1, x2)),
(max(y1, y2), max(x1, x2)),
]
)
- V
)
== 0
):
if _within(W, a, b, T, R, B, L):
p2 = max(p2, max(p2, x * y))
return p1, p2
if __name__ == "__main__":
inp = """
7,1
11,1
11,7
9,7
9,5
2,5
2,3
7,3 """.strip()
def _within(W, a, b, T, R, B, L):
y1, x1 = a
y2, x2 = b
for r in range(min(y1, y2) + 1, max(y1, y2)):
for c in range(min(x1, x2) + 1, max(x1, x2)):
if (r, c) in W:
continue
for s, e in [(T, r), (r, B)]:
z = sum((nr, c) in W for nr in range(s, e))
if z and z % 2 == 0:
return False
for s, e in [(L, c), (c, R)]:
z = sum((r, nc) in W for nc in range(s, e))
if z and z % 2 == 0:
return False
return True
if __name__ == "__main__":
with open("./input/09.txt", "r") as f:
inp = f.read().strip()