Skip to content

Commit dd490a2

Browse files
committed
2023 day 3 part 2 (incorrect)
1 parent b9b7dbb commit dd490a2

File tree

1 file changed

+76
-10
lines changed

1 file changed

+76
-10
lines changed

2023/day03.py

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,101 @@
11
import re
2+
from collections import namedtuple
3+
from itertools import combinations
24

5+
Point = namedtuple("Point", ["x", "y"])
6+
BoundingBox = namedtuple("BoundingBox", ["bottom_left", "top_right"])
37

4-
def part_number_count(schematic):
8+
9+
def intersects(bbox_a, bbox_b):
10+
# Adapted from https://stackoverflow.com/a/40795835
11+
return not (
12+
bbox_a.top_right.x < bbox_b.bottom_left.x
13+
or bbox_a.bottom_left.x > bbox_b.top_right.x
14+
or bbox_a.top_right.y > bbox_b.bottom_left.y
15+
or bbox_a.bottom_left.y < bbox_b.top_right.y
16+
)
17+
18+
19+
def overlapping_content(bbox_a, bbox_b, rows):
20+
# Calculate the max bounding box
21+
# x_start = min(bbox_a.bottom_left.x, bbox_b.bottom_left.x)
22+
# x_end = max(bbox_a.top_right.x, bbox_b.top_right.x)
23+
# y_start = min(bbox_a.top_right.y, bbox_b.top_right.y)
24+
# y_end = max(bbox_a.bottom_left.y, bbox_b.bottom_left.y)
25+
#
26+
# overlapping_text = []
27+
# for y in range(y_start, y_end + 1):
28+
# row_content = rows[y]
29+
# overlapping_text.append(row_content[x_start : x_end + 1])
30+
# print("\n".join(overlapping_text))
31+
32+
# Calculate the overlapping region
33+
x_start = max(bbox_a.bottom_left.x, bbox_b.bottom_left.x)
34+
x_end = min(bbox_a.top_right.x, bbox_b.top_right.x)
35+
y_start = max(bbox_a.top_right.y, bbox_b.top_right.y)
36+
y_end = min(bbox_a.bottom_left.y, bbox_b.bottom_left.y)
37+
38+
overlapping_text = []
39+
for y in range(y_start, y_end + 1):
40+
row_content = rows[y]
41+
overlapping_text.append(row_content[x_start : x_end + 1])
42+
return "\n".join(overlapping_text)
43+
44+
45+
def part_number_count(schematic, part=1):
546
part_numbers = 0
647
rows = schematic.splitlines()
748
width = len(rows[0])
849
new_rows = ["." * (width + 2)] + [f".{row}." for row in rows] + ["." * (width + 2)]
9-
# print('\n'.join(new_rows))
50+
51+
bounding_boxes = {}
1052
for row_nr, line in enumerate(new_rows):
1153
matches = re.finditer(r"\d+", line)
1254
for match in matches:
1355
number = int(match.group())
1456
start = match.start()
1557
end = match.end() # End position (exclusive)
16-
# print(f"Number: {number}, Start: {start}, End: {end}, row nr {row_nr}")
1758

18-
symbols = []
1959
position_before = start - 1
20-
symbols.append(new_rows[row_nr][position_before])
2160
position_after = end
22-
symbols.append(new_rows[row_nr][position_after])
2361
row_nr_above = row_nr - 1
24-
symbols.extend(new_rows[row_nr_above][position_before : position_after + 1])
2562
row_nr_below = row_nr + 1
63+
64+
symbols = []
65+
symbols.append(new_rows[row_nr][position_before])
66+
symbols.append(new_rows[row_nr][position_after])
67+
symbols.extend(new_rows[row_nr_above][position_before : position_after + 1])
2668
symbols.extend(new_rows[row_nr_below][position_before : position_after + 1])
27-
# print(set(symbols))
69+
2870
if len(set(symbols)) > 1:
2971
part_numbers += number
30-
return part_numbers
72+
73+
if part == 2:
74+
if "*" in symbols:
75+
bottom_left = Point(position_before, row_nr_below)
76+
top_right = Point(position_after, row_nr_above)
77+
bounding_boxes[number] = BoundingBox(bottom_left, top_right)
78+
79+
if part == 1:
80+
return part_numbers
81+
else:
82+
gear_ratio = 0
83+
for part_number_a, part_number_b in combinations(
84+
sorted(bounding_boxes.keys()), 2
85+
):
86+
bbox_a = bounding_boxes[part_number_a]
87+
bbox_b = bounding_boxes[part_number_b]
88+
if intersects(bbox_a, bbox_b) and "*" in overlapping_content(
89+
bbox_a, bbox_b, new_rows
90+
):
91+
gear_ratio += part_number_a * part_number_b
92+
return gear_ratio
3193

3294

3395
def main(part: int = 1) -> int:
3496
with open("2023/data/day03.txt") as f:
3597
schematic = f.read()
36-
return part_number_count(schematic)
98+
return part_number_count(schematic, part)
3799

38100

39101
if __name__ == "__main__":
@@ -51,3 +113,7 @@ def main(part: int = 1) -> int:
51113
assert part_number_count(schematic) == 4361
52114

53115
print(main())
116+
117+
assert part_number_count(schematic, part=2) == 467835
118+
119+
print(main(part=2))

0 commit comments

Comments
 (0)