1
0
Fork 0
advent-of-code/2023/day03.py

97 lines
No EOL
2.4 KiB
Python

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