Day 03
This commit is contained in:
parent
fbc14bd38b
commit
a115eadafe
2 changed files with 100 additions and 1 deletions
2
aoc.py
2
aoc.py
|
@ -125,7 +125,7 @@ class Aoc(Generic[T1], Aoc2[T1, T1]):
|
||||||
return self.part1(inpt)
|
return self.part1(inpt)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main() -> None:
|
||||||
days = [
|
days = [
|
||||||
import_module(file.stem)
|
import_module(file.stem)
|
||||||
for file in Path(".").iterdir()
|
for file in Path(".").iterdir()
|
||||||
|
|
99
day03.py
Normal file
99
day03.py
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
from collections import defaultdict
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from functools import reduce
|
||||||
|
from typing import Any, Optional
|
||||||
|
from aoc import Aoc
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Number:
|
||||||
|
value: int
|
||||||
|
symbol: Optional[tuple[int, int, str]]
|
||||||
|
startx: int
|
||||||
|
endx: int
|
||||||
|
linenr: int
|
||||||
|
|
||||||
|
|
||||||
|
class Day03(Aoc[list[Number]]):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__(2023, 3)
|
||||||
|
|
||||||
|
def get_symbol(
|
||||||
|
self, inpt: list[str], startx: int, endx: int, liney: int
|
||||||
|
) -> Optional[tuple[int, int, str]]:
|
||||||
|
symbol = None
|
||||||
|
for x in range(max(0, startx - 1), min(len(inpt[0]), endx + 1)):
|
||||||
|
yrange = [liney - 1, liney, liney + 1]
|
||||||
|
if x != startx - 1 and x != endx:
|
||||||
|
yrange.remove(liney)
|
||||||
|
if liney == 0:
|
||||||
|
yrange.remove(liney - 1)
|
||||||
|
if liney == len(inpt) - 1:
|
||||||
|
yrange.remove(liney + 1)
|
||||||
|
for y in yrange:
|
||||||
|
try:
|
||||||
|
if inpt[y][x] != "." and not inpt[y][x].isnumeric():
|
||||||
|
symbol = (x, y, inpt[y][x])
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
return symbol
|
||||||
|
|
||||||
|
def parseinput(self, inpt: str) -> list[Number]:
|
||||||
|
numbers = []
|
||||||
|
lines = inpt.splitlines()
|
||||||
|
for posy, line in enumerate(lines):
|
||||||
|
num_accum = None
|
||||||
|
firstx = 0
|
||||||
|
lastx = 0
|
||||||
|
for posx, char in enumerate(line):
|
||||||
|
if char.isnumeric():
|
||||||
|
if num_accum is None:
|
||||||
|
num_accum = char
|
||||||
|
firstx = posx
|
||||||
|
else:
|
||||||
|
num_accum += char
|
||||||
|
else:
|
||||||
|
if num_accum is not None:
|
||||||
|
lastx = posx
|
||||||
|
symbol = self.get_symbol(lines, firstx, lastx, posy)
|
||||||
|
numbers.append(
|
||||||
|
Number(int(num_accum), symbol, firstx, lastx, posy)
|
||||||
|
)
|
||||||
|
|
||||||
|
num_accum = None
|
||||||
|
firstx = 0
|
||||||
|
lastx = 0
|
||||||
|
|
||||||
|
if num_accum is not None:
|
||||||
|
lastx = len(line)
|
||||||
|
symbol = self.get_symbol(lines, firstx, lastx, posy)
|
||||||
|
numbers.append(Number(int(num_accum), symbol, firstx, lastx, posy))
|
||||||
|
|
||||||
|
num_accum = None
|
||||||
|
firstx = 0
|
||||||
|
lastx = 0
|
||||||
|
|
||||||
|
return numbers
|
||||||
|
|
||||||
|
def part1(self, inpt: list[Number]) -> int:
|
||||||
|
return sum([number.value for number in inpt if number.symbol is not None])
|
||||||
|
|
||||||
|
def part2(self, inpt: list[Number]) -> Any:
|
||||||
|
gears_to_number = defaultdict(list)
|
||||||
|
for number in inpt:
|
||||||
|
if number.symbol is not None and number.symbol[2] == "*":
|
||||||
|
gears_to_number[number.symbol].append(number.value)
|
||||||
|
return sum(
|
||||||
|
reduce(lambda x, y: x * y, numbers)
|
||||||
|
for numbers in gears_to_number.values()
|
||||||
|
if len(numbers) == 2
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
day03 = Day03()
|
||||||
|
day03.run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Add table
Reference in a new issue