80 lines
2.2 KiB
Python
Executable File
80 lines
2.2 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)
|
|
selected_numbers = []
|
|
for line_no in range(len(lines)):
|
|
for symbol in filter(lambda symbol: symbol.y == line_no, 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)
|
|
)
|
|
|
|
sym_selected = list(filter(selection, numbers))
|
|
selected_numbers += sym_selected
|
|
# print(symbol, sym_selected)
|
|
# print("")
|
|
selected_numbers = set(selected_numbers)
|
|
# pprint(selected_numbers)
|
|
print(sum(list(map(lambda number: number.value, selected_numbers))))
|