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
84 lines
2 KiB
Python
84 lines
2 KiB
Python
from math import inf
|
|
from itertools import combinations
|
|
|
|
from output import ints
|
|
|
|
|
|
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()
|
|
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]
|
|
if not he and not ve:
|
|
E = A[0]
|
|
elif he and ve:
|
|
E = min(min(he), min(ve))
|
|
elif he and not ve:
|
|
E = min(he)
|
|
else:
|
|
E = min(ve)
|
|
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):
|
|
W.add((r, c))
|
|
if E == A[0]:
|
|
break
|
|
S = E
|
|
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 _within(W, a, b, T, R, B, L):
|
|
p2 = max(p2, max(p2, x * y))
|
|
return p1, p2
|
|
|
|
|
|
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()
|
|
|
|
p1, p2 = solve(inp)
|
|
|
|
print(p1)
|
|
print(p2)
|
|
|
|
assert p1 == 4749838800
|
|
assert p2 == 1624057680
|