61 lines
1.1 KiB
Python
61 lines
1.1 KiB
Python
|
from re import finditer
|
||
|
from collections import defaultdict
|
||
|
from math import prod
|
||
|
|
||
|
with open("input.txt") as f:
|
||
|
lines = f.read().split("\n")
|
||
|
|
||
|
### part 1
|
||
|
|
||
|
symbols = {
|
||
|
(i,j)
|
||
|
for i, line in enumerate(lines)
|
||
|
for j, c in enumerate(line)
|
||
|
if c not in "1234567890."
|
||
|
}
|
||
|
|
||
|
part_numbers = []
|
||
|
|
||
|
for i, line in enumerate(lines):
|
||
|
for match in finditer(r"\d+", line):
|
||
|
j1, j2 = match.span()
|
||
|
number = int(match[0])
|
||
|
window = {
|
||
|
(i+x, j+y)
|
||
|
for x in (-1, 0, 1)
|
||
|
for y in (-1, 0, 1)
|
||
|
for j in range(j1, j2)
|
||
|
}
|
||
|
for _ in window & symbols:
|
||
|
part_numbers.append(number)
|
||
|
|
||
|
part1 = sum(part_numbers)
|
||
|
print(part1)
|
||
|
|
||
|
### part 2
|
||
|
|
||
|
potential_gears = {
|
||
|
(i,j)
|
||
|
for i, line in enumerate(lines)
|
||
|
for j, c in enumerate(line)
|
||
|
if c == "*"
|
||
|
}
|
||
|
|
||
|
parts = defaultdict(list)
|
||
|
|
||
|
for i, line in enumerate(lines):
|
||
|
for match in finditer(r"\d+", line):
|
||
|
j1, j2 = match.span()
|
||
|
number = int(match[0])
|
||
|
window = {
|
||
|
(i+x, j+y)
|
||
|
for x in (-1, 0, 1)
|
||
|
for y in (-1, 0, 1)
|
||
|
for j in range(j1, j2)
|
||
|
}
|
||
|
for cell in window & potential_gears:
|
||
|
parts[cell].append(number)
|
||
|
|
||
|
gear_ratios = (prod(p) for p in parts.values() if len(p) == 2)
|
||
|
part2 = sum(gear_ratios)
|
||
|
print(part2)
|