1
0
Fork 0
adventofcode/2023/03/main.py
2024-12-30 19:45:55 +01:00

69 lines
1.8 KiB
Python

#!/usr/bin/env python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# Author: Sebastian Mark
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
import re
def readinput():
with open("input", "r", encoding="utf-8") as file:
lines = [line.rstrip("\n") for line in file.readlines()]
return lines
def find_numbers(lines: list) -> set:
# create a set of [(y,x,number),(y,x,number)]
numbers = set()
for y, line in enumerate(lines):
matches = re.finditer(r"\d+", line)
for match in matches:
x = match.start()
numbers.add((y, x, match.group()))
return numbers
def check_partnumber(lines: list, starty: int, startx: int, partnumber: str) -> bool:
directions = [
(-1, 0), # Up
(-1, 1), # Up-right
(0, 1), # Right
(1, 1), # Down-right
(1, 0), # Down
(1, -1), # Down-left
(0, -1), # Left
(-1, -1), # Up-left
]
width = len(lines[0])
height = len(lines)
for charpos in range(
startx, startx + len(partnumber)
): # for all numbers in the partnumber
for dy, dx in directions: # check all directions
nxty, nxtx = starty + dy, charpos + dx # new checkposition
if 0 <= nxtx < width and 0 <= nxty < height: # validate borders
if lines[nxty][nxtx] not in "0123456789.":
return True # found symbol, this is a valid partnumber
return False
def main():
lines = readinput()
numbers = find_numbers(lines)
# part 1
count = 0
for y, x, number in numbers:
if check_partnumber(lines, y, x, number):
count += int(number)
print("Sum of partnumbers: %d" % count)
if __name__ == "__main__":
main()