advent-of-code-2025/day02.py
Tobias Radloff c423502b2b
Day 2
2025-12-02 10:17:32 +01:00

75 lines
2.1 KiB
Python

#!/usr/bin/env python
import re
from functools import reduce
f = open("day02input.txt", "r")
a = f.readline().strip().split(",")
def get_re(pat_len: int, pat_num: int = 2) -> re.Pattern:
return re.compile((r"(" + r"\d" * pat_len + r")") * pat_num)
def part1(data: list[str]) -> int:
bad_ids = 0
r = {}
for id_set in data:
_from, _to = id_set.split("-")
# loop over IDs in range
for _id in range(int(_from), int(_to) + 1):
id_len = len(str(_id))
# weed out IDs with odd number of digits
if id_len % 2 == 1:
continue
hl = str(id_len // 2)
# check if compiled re is already in dict; add if not
if not hl in r.keys():
r[hl] = get_re(int(hl))
# match ID and check if first and second halves are equal
m = r[hl].match(str(_id))
if m.group(1) == m.group(2):
bad_ids += _id
return bad_ids
def part2(data: list[str]) -> int:
bad_ids = set() # collect invalid IDs in a set to avoid adding counting the same ID multiple times
r = {}
for id_set in data:
_from, _to = id_set.split("-")
# loop over IDs in range
for _id in range(int(_from), int(_to) + 1):
id_len = len(str(_id))
# loop over pattern lengths
for pat_len in range(1, (id_len // 2) + 1):
# weed out IDs where ID length is not a multiple of pattern length
if id_len % pat_len != 0:
continue
pat_num = id_len // pat_len
# check if compiled re is already in dict; add if not
if not str(pat_len) in r.keys():
r[str(pat_len)] = {}
if not str(pat_num) in r[str(pat_len)].keys():
r[str(pat_len)][str(pat_num)] = get_re(pat_len, pat_num)
print(f"RE:\t{_id}\t\t{pat_len}\t{pat_num}\t{r[str(pat_len)][str(pat_num)]}")
# match ID and check if all groups are equal
m = r[str(pat_len)][str(pat_num)].match(str(_id))
if len(set(m.groups())) == 1:
print(f"Match:\t{_id}\t\t{pat_len}\t{pat_num}\t{r[str(pat_len)][str(pat_num)]}")
bad_ids.add(_id)
return sum(bad_ids)
print(part1(a))
print(part2(a))