diff --git a/3/engine.py b/3/engine.py new file mode 100644 index 0000000..6f19640 --- /dev/null +++ b/3/engine.py @@ -0,0 +1,58 @@ +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")] + + # get coordinates of numbers + nums = { + (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 + for n in re.finditer(r"\d+", row): + edge = { + (i, char) + for i in (i - 1, i, i + 1) + for char in range(n.start() - 1, n.end() + 1) + } + for o in edge & nums.keys(): + nums[o].append(int(n.group())) + return nums + + +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)