2023/day03.py

90 lines
1.9 KiB
Python
Raw Permalink Normal View History

2023-12-05 09:56:37 +00:00
import fileinput
from pprint import pprint
inp = []
for line in fileinput.input():
if line:
inp.append(list(line.strip()))
numbers = {}
gear_numbers = {}
2023-12-05 09:59:06 +00:00
2023-12-05 09:56:37 +00:00
def moore(x, y):
for j in (-1, 0, 1):
for i in (-1, 0, 1):
if (
not (i == 0 and j == 0)
and 0 <= (y + j) < len(inp)
and 0 <= (x + i) < len(inp[y + j])
):
yield (x + i, y + j)
for y in range(len(inp)):
for x in range(len(inp[y])):
2023-12-05 09:59:06 +00:00
if not inp[y][x].isdigit():
continue
while x >= 0 and inp[y][x].isdigit():
x -= 1
x += 1
if (x, y) in numbers:
continue
is_part_number = False
gear = None
x_ = x
number = 0
while x_ < len(inp[y]) and inp[y][x_].isdigit():
number = number * 10 + int(inp[y][x_])
for i, j in moore(x_, y):
if not inp[j][i].isdigit() and inp[j][i] != ".":
is_part_number = True
if inp[j][i] == "*":
gear = (i, j)
break
x_ += 1
if is_part_number:
numbers[(x, y)] = number
2023-12-05 09:56:37 +00:00
2023-12-05 09:59:06 +00:00
if not gear or (x, y) in gear_numbers:
continue
gear_number = 0
for i, j in moore(*gear):
if not inp[j][i].isdigit():
2023-12-05 09:56:37 +00:00
continue
2023-12-05 09:59:06 +00:00
while j >= 0 and inp[j][i].isdigit():
i -= 1
i += 1
if (i, j) in gear_numbers:
break
if (x, y) == (i, j):
continue
i_ = i
while i_ < len(inp[j]) and inp[j][i_].isdigit():
gear_number = gear_number * 10 + int(inp[j][i_])
i_ += 1
gear_number *= number
gear_numbers[(x, y)] = gear_number
break
part1 = sum(numbers.values())
2023-12-05 09:56:37 +00:00
part2 = sum(gear_numbers.values())
2023-12-05 09:59:06 +00:00
print(part1, part2)