From 0dcd6750425e37d58a52ac62fb0489e4c52d7e37 Mon Sep 17 00:00:00 2001 From: Andrew Ekstedt Date: Tue, 9 Dec 2025 06:38:54 +0000 Subject: [PATCH] day 9 cleanup --- day09/sol.py | 60 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/day09/sol.py b/day09/sol.py index 007c574..547c3a1 100644 --- a/day09/sol.py +++ b/day09/sol.py @@ -1,31 +1,54 @@ from math import dist + def solve(input): points = [] for line in open(input): x,y = map(int, line.strip().split(",")) points.append((x,y)) + # Part 1: + # find the largest rectangle created by two points + def areas(): for p in points: for q in points: if p != q: yield area(p,q) + # answer 1 print(max(areas())) + # Part 2: + # find the largest rectangle formed by a pair of points + # which is contained within the polygon defined by the list of points. + lines = list(zip(points, points[1:]+[points[0]])) - # keep only vertical lines, and sort so the uppermost point (lowest x coord) is the first of the pair + # keep only vertical lines, and sort so the uppermost point (lowest y coord) is the first of the pair lines = [(min(p,q),max(p,q)) for p,q in lines if p[1] != q[1]] - # sort by y coord + # sort lines by y coord lines.sort(key=lambda l: (l[0][1],l[1][1],l[0][0],l[1][0])) - print(lines) + + #print(lines) # we want to know if the rectangle formed by a pair of points - # is completely contained within the axis-aligned polygon defined - # by the list of points. - # we can do that with a scanline algorithm: - # for each x position in the list of points, + # is completely contained within an axis-aligned polygon. # + # we can do that with a pseudo-scanline algorithm. + # + # we make a couple simplifying assumptions: + # 1. first, that the polygon is not self-intersecting + # 2. second, that the polygon is not "U shaped" -- + # that is, it has a definite, single width in every horizontal slice + # and it doesn't curve around at all -- so we don't have to worry + # about voids + # + # for each y position, we first calculate the horizontal bounds of the + # polygon at that line. + # + # then, to test if a rectangle is contained within the polygon, + # we just need to iterate through the y positions which fall inside the rectangle + # and check whether the rectangle would exceed the previously computed bounds + # of the polygon at any of those points. bounds = {} ys = sorted(set(p[1] for l in lines for p in l)) @@ -34,11 +57,14 @@ def solve(input): mylines = [] for p,q in lines: if p[1] <= y <= q[1]: - mylines.append(p[0]) + mylines.append(p[0]) # only keep the x coord + # since we are assuming no self-intersection and no voids, + # the bounds on this line are just the leftmost and rightmost + # x coordinate of the intersecting lines bounds[y] = (min(mylines),max(mylines)) - print(ys) - print(bounds) + #print(ys) + #print(bounds) def inbounds(p,q): y0 = min(p[1],q[1]) @@ -46,21 +72,23 @@ def solve(input): x0 = min(p[0],q[0]) x1 = max(p[0],q[0]) #print(y0, y1, ys) - i = ys.index(y0) - j = ys.index(y1) + 1 - for y in ys[i:j]: + start = ys.index(y0) + for i in range(start,len(ys)): + y = ys[i] + if y > y1: + break if not bounds[y][0] <= x0 <= x1 <= bounds[y][1]: return False return True - def areas2(): + def inbound_areas(): for p in points: for q in points: if p != q and inbounds(p,q): yield area(p,q) - print(max(areas2())) - + # answer 2 + print(max(inbound_areas())) def area(p,q): dx = abs(p[0] - q[0]) + 1