#!/usr/bin/env python3 lines = [] with open('./inputs/day03.txt') as f: lines = f.readlines() class Point: def __init__(self, x, y): self.x = x self.y = y def __str__(self): return f'({self.x}, {self.y})' class Number: def __init__(self, start, end, digits): self.start = start self.end = end self.digits = digits self.value = int(f''.join(map(str, digits))) def __str__(self): return f'({self.start}, {self.end}, {self.digits}, {self.value})' def adjacentToSymbols(self, symbols): for symbol in symbols: if self.adjacentTo(symbol): return True return False def adjacentTo(self, symbol): if abs(self.start.y - symbol.y) <= 1 and ((self.start.x - 1) <= symbol.x <= (self.end.x + 1)): return True return False class Symbol: def __init__(self, x, y, value): self.x = x self.y = y self.value = value def __str__(self): return f'({self.x}, {self.y}, {self.value})' def gearRatio(self, numbers): if not self.value == '*': return -1 adjacent = [] for number in numbers: if number.adjacentTo(self): adjacent.append(number) if len(adjacent) == 2: return adjacent[0].value * adjacent[1].value return -1 # part 1 numbers = [] symbols = [] for y in range(len(lines)): line = lines[y] digits = [] numberStarted = False start = None end = None for x in range(len(line)): ch = line[x] if (ch == '.' and not numberStarted): continue if (ch.isdigit() and not numberStarted): numberStarted = True start = Point(x, y) if (ch.isdigit()): digits.append(int(ch)) if ((not ch.isdigit()) and numberStarted): end = Point(x - 1, y) numbers.append(Number(start, end, digits)) numberStarted = False digits = [] if ((not ch.isdigit()) and (not ch == '.') and (not ch == '\n')): symbols.append(Symbol(x, y, ch)) print(f'Part 1: {sum([number.value for number in numbers if number.adjacentToSymbols(symbols)])}') # part 2 print(f'Part 2: {sum([symbol.gearRatio(numbers) for symbol in symbols if symbol.gearRatio(numbers) > 0])}')