aoc2023/day03.py

93 lines
2.5 KiB
Python

from tools.aoc import AOCDay
from typing import Any
from tools.coordinate import Coordinate
from tools.grid import Grid
class Day(AOCDay):
inputs = [
[
(4361, "input3_test"),
(533775, "input3_dennis"),
(560670, "input3"),
],
[
(467835, "input3_test"),
(78236071, "input3_dennis"),
(91622824, "input3"),
],
]
def parse_input(self) -> Grid:
grid = Grid()
num_found = 0
number_digits = set()
number = 0
for y, l in enumerate(self.getInput()):
for x, c in enumerate(l):
if c.isdigit():
number_digits.add((x, y))
number = number * 10 + int(c)
else:
if number_digits:
for nc in number_digits:
grid.set(Coordinate(*nc), (num_found, number))
num_found += 1
number_digits = set()
number = 0
if c != ".":
grid.set(Coordinate(x, y), c)
return grid
def part1(self) -> Any:
grid = self.parse_input()
part_number_sum = 0
seen = set()
for c in grid.getActiveCells():
v = grid.get(c)
if not isinstance(v, tuple):
continue
num_id, num_value = v
if num_id in seen:
continue
for n in grid.getNeighboursOf(c, includeDefault=False, includeDiagonal=True):
nv = grid.get(n)
if nv and not isinstance(nv, tuple):
part_number_sum += num_value
seen.add(num_id)
break
return part_number_sum
def part2(self) -> Any:
grid = self.parse_input()
gear_ratio_sum = 0
for c in grid.getActiveCells():
if grid.get(c) != "*":
continue
count = 0
ratio = 1
seen = set()
for n in grid.getNeighboursOf(c, includeDiagonal=True, includeDefault=False):
num = grid.get(n)
if num and isinstance(num, tuple) and num[0] not in seen:
ratio *= num[1]
count += 1
seen.add(num[0])
if count == 2:
gear_ratio_sum += ratio
return gear_ratio_sum
if __name__ == "__main__":
day = Day(2023, 3)
day.run(verbose=True)