From 0000027078560fba1bc4c1fe3033a5e0d1af76e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Jane=C5=BEi=C4=8D?= Date: Thu, 18 Dec 2025 09:34:07 +0100 Subject: [PATCH] perf: optimize solution 2025/03 --- src/solution/year_2025/day_03.py | 65 +++++++++++++------------------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/src/solution/year_2025/day_03.py b/src/solution/year_2025/day_03.py index 9081e4d..fbdec50 100644 --- a/src/solution/year_2025/day_03.py +++ b/src/solution/year_2025/day_03.py @@ -1,59 +1,46 @@ from typing import Any -def find_max_subnumber(numbers: list[int], length: int) -> int: - numbers = list(reversed(numbers)) - max_search_index = len(numbers) - n = 0 - +def _find_max_subnumber(numbers: list[int], length: int) -> int: if length > len(numbers): raise ValueError("length greater than numbers length") - for start_idx in range(length - 1, -1, -1): - # local number and loacal max search index - ln, lmsi = 0, 0 - # search from start_idx up to max_search_index - for idx in range(start_idx, max_search_index): - m = numbers[idx] - if idx >= max_search_index: - max_search_index = lmsi - break - # find leftmost highst number and update found digit and local max index - if m >= ln: - ln = m - lmsi = idx + remove = len(numbers) - length + stack = [] - max_search_index = lmsi - n += ln - n *= 10 + for n in numbers: + while remove and stack and stack[-1] < n: + stack.pop() + remove -= 1 + stack.append(n) - return n // 10 + res = 0 + for digit in stack[:length]: + res = res * 10 + digit + + return res + + +def _parse_input(input_data: str) -> list[list[int]]: + return [list(map(int, line)) for line in input_data.splitlines()] def part_1(input_data: str) -> Any: - s = 0 - for line in input_data.splitlines(): - parsed = list(map(int, line)) - s += find_max_subnumber(parsed, 2) - return s + return sum(_find_max_subnumber(p, 2) for p in _parse_input(input_data)) def part_2(input_data: str) -> Any: - s = 0 - for line in input_data.splitlines(): - parsed = list(map(int, line)) - s += find_max_subnumber(parsed, 12) - return s + return sum(_find_max_subnumber(p, 12) for p in _parse_input(input_data)) def test_find_max_subnumber(): - assert find_max_subnumber([1, 2, 3, 4, 9], 2) == 49 - assert find_max_subnumber([1, 2, 3, 4, 5], 2) == 45 - assert find_max_subnumber([5, 4, 3, 2, 1], 2) == 54 - assert find_max_subnumber([1, 3, 5, 2, 4], 2) == 54 - assert find_max_subnumber([8, 1, 8, 2, 7, 3], 3) == 887 - assert find_max_subnumber([1, 9, 2, 8, 3, 7], 3) == 987 - assert find_max_subnumber([1, 2, 3, 4, 5], 3) == 345 + assert _find_max_subnumber([1, 2, 3, 4, 9], 2) == 49 + assert _find_max_subnumber([1, 2, 3, 4, 5], 2) == 45 + assert _find_max_subnumber([5, 4, 3, 2, 1], 2) == 54 + assert _find_max_subnumber([1, 3, 5, 2, 4], 2) == 54 + assert _find_max_subnumber([8, 1, 8, 2, 7, 3], 3) == 887 + assert _find_max_subnumber([1, 9, 2, 8, 3, 7], 3) == 987 + assert _find_max_subnumber([1, 2, 3, 4, 5], 3) == 345 def test_part_1(example_data):