Files
adventofcode2023/3/engine.py
2023-12-03 21:07:11 +01:00

61 lines
1.7 KiB
Python

from aocd.models import Puzzle
from aocd import submit
from dataclasses import dataclass
import math
import re
def parse_input(input_data: str) -> dict:
"""
Parse input and filter
- first get positions of all numbers in field
- read their value if there is an adjacent symbol
Assumptions to greatly simplify the task (thx reddit):
- No number touches more than one symbol
- No non-star symbol touches exactly two numbers
"""
# convert input into a 2d array for easier parsing
field = [line for line in input_data.split("\n")]
# create a dictionary of all symbols and their coordinates
symbols = {
(i, char): []
for i in range(140)
for char in range(140)
if field[i][char] not in "01234566789."
}
# for each row in field
for i, row in enumerate(field):
# for each number in row create a dictionary of any number with coords
for n in re.finditer(r"\d+", row):
numbers = {
(i, char)
for i in (i - 1, i, i + 1)
for char in range(n.start() - 1, n.end() + 1)
}
# append each number to the list of numbers
for o in numbers & symbols.keys():
symbols[o].append(int(n.group()))
return symbols
if __name__ == "__main__":
# get puzzle and parse data
puzzle = Puzzle(year=2023, day=3)
# parse_input(puzzle.input_data)
nums = parse_input(puzzle.input_data)
# part a:
answer_a = sum(sum(p) for p in nums.values())
print(f"{answer_a}")
submit(answer_a, part="a", day=3, year=2023)
# part b:
answer_b = sum(math.prod(p) for p in nums.values() if len(p) == 2)
print(f"{answer_b}")
submit(answer_b, part="b", day=3, year=2023)