# Advent of code 2023 day 3

Dec 3rd, 2023 (edited)
995
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. def day3(s, *, part2=False):
2.   grid = np.pad([list(line) for line in s.splitlines()], 1, constant_values='.')
3.
4.   def neighbors(y, x):
5.     for dy, dx in set(itertools.product((-1, 0, 1), repeat=2)) - {(0, 0)}:
6.       yield y + dy, x + dx
7.
8.   def number_span(y, x):
9.     while grid[y, x - 1].isdigit():  # Move to first digit.
10.       x -= 1
11.     x_start = x
12.     while grid[y, x].isdigit():  # Move past last digit.
13.       x += 1
14.     return y, x_start, x
15.
17.     return {number_span(*yx2) for yx2 in neighbors(*yx) if grid[yx2].isdigit()}
18.
19.   def get_value(y, x_start, x_stop):
20.     return int(''.join(grid[y, x_start:x_stop]))
21.
22.   if part2:
23.     yxs = (yx for yx, ch in np.ndenumerate(grid) if ch == '*')
24.     gears = (spans for yx in yxs if len(spans := adjacent_number_spans(yx)) == 2)
25.     return sum(math.prod(get_value(*span) for span in gear) for gear in gears)
26.
27.   else:
28.     yxs = (yx for yx, ch in np.ndenumerate(grid) if ch not in '.0123456789')
29.     spans = set.union(*(adjacent_number_spans(yx) for yx in yxs))
30.     return sum(get_value(*span) for span in spans)