2023/day3/part2.py
2023-12-03 08:41:27 +01:00

78 lines
2.1 KiB
Python
Executable File

#!/usr/bin/env python3.11
from dataclasses import dataclass
from typing import List
from pprint import pprint
import re
@dataclass
class Point:
x: int
y: int
def __hash__(self):
return (self.x, self.y).__hash__()
@dataclass
class Number:
value: int
start: Point
end: Point
def __hash__(self):
return (self.value, self.start, self.end).__hash__()
@dataclass
class Symbol(Point):
value: str
lines = []
numbers: List[Number] = []
symbols: List[Symbol] = []
with open("input.txt") as input:
lines = input.readlines()
for line_no, line in enumerate(lines):
idx = 0
while match := re.match("\.*(\d+|[^\.\d\n]).*", line[idx:]):
rec = match.group(1)
place = line[idx:].find(rec)
if re.match("\d+", rec):
number = Number(
value=int(rec),
start=Point(x=idx + place, y=line_no),
end=Point(x=idx + place + len(rec) - 1, y=line_no),
)
numbers.append(number)
# print(number)
idx += place + len(rec)
else:
symbol = Symbol(value=rec, x=idx + place, y=line_no)
symbols.append(symbol)
# print(symbol)
idx += place + 1
# pprint(numbers)
# pprint(symbols)
the_sum = 0
for line_no in range(len(lines)):
for symbol in filter(lambda symbol: symbol.y == line_no and symbol.value == "*", symbols):
# print(symbol.value, end="")
def selection(number: Number):
return (
(number.start.y == line_no - 1 and number.start.x <= symbol.x + 1 and number.end.x >= symbol.x - 1)
or (number.start.y == line_no + 1 and number.start.x <= symbol.x + 1 and number.end.x >= symbol.x - 1)
or (number.end.x == symbol.x - 1 and number.end.y == line_no)
or (number.start.x == symbol.x + 1 and number.start.y == line_no)
)
selected = list(filter(selection, numbers))
if len(selected) == 2:
# print(symbol, selected)
the_sum += selected[0].value * selected[1].value
print(the_sum)