#!/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))))