import math from typing import Any def _cut_right_n_digits(s: int, n: int) -> tuple[int, int]: left = s // 10**n right = s - left * 10**n return left, right def is_invalid(n: int) -> bool: size = int(math.log10(n)) + 1 left, right = _cut_right_n_digits(n, size // 2) return left == right def is_invalid_any(n: int) -> bool: size = int(math.log10(n)) + 1 for cut in range(1, size): if size % cut != 0: continue left, right = _cut_right_n_digits(n, cut) while left != 0: nleft, nright = _cut_right_n_digits(left, cut) if nright != right: break left = nleft if left == 0: return True return False def part_1(input_data: str) -> Any: s = 0 for rng in input_data.split(","): a, b = (int(s) for s in rng.split("-")) s += sum([n for n in range(a, b + 1) if is_invalid(n)]) return s def part_2(input_data: str) -> Any: s = 0 for rng in input_data.split(","): a, b = (int(s) for s in rng.split("-")) s += sum([n for n in range(a, b + 1) if is_invalid_any(n)]) return s def test_is_invalid(): assert is_invalid(55) assert is_invalid(6464) assert is_invalid(123123) assert not is_invalid(123124) assert not is_invalid(22222) def test_is_invalid_any(): assert is_invalid_any(12341234) assert is_invalid_any(123123123) assert is_invalid_any(12121212) assert is_invalid_any(1111111) assert not is_invalid_any(123124) assert not is_invalid_any(12312) def test_part_1(example_data): assert part_1(example_data) == 1227775554 def test_part_2(example_data): assert part_2(example_data) == 4174379265