perf: optimize solution 2025/03
This commit is contained in:
@@ -1,59 +1,46 @@
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
def find_max_subnumber(numbers: list[int], length: int) -> int:
|
def _find_max_subnumber(numbers: list[int], length: int) -> int:
|
||||||
numbers = list(reversed(numbers))
|
|
||||||
max_search_index = len(numbers)
|
|
||||||
n = 0
|
|
||||||
|
|
||||||
if length > len(numbers):
|
if length > len(numbers):
|
||||||
raise ValueError("length greater than numbers length")
|
raise ValueError("length greater than numbers length")
|
||||||
|
|
||||||
for start_idx in range(length - 1, -1, -1):
|
remove = len(numbers) - length
|
||||||
# local number and loacal max search index
|
stack = []
|
||||||
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
|
|
||||||
|
|
||||||
max_search_index = lmsi
|
for n in numbers:
|
||||||
n += ln
|
while remove and stack and stack[-1] < n:
|
||||||
n *= 10
|
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:
|
def part_1(input_data: str) -> Any:
|
||||||
s = 0
|
return sum(_find_max_subnumber(p, 2) for p in _parse_input(input_data))
|
||||||
for line in input_data.splitlines():
|
|
||||||
parsed = list(map(int, line))
|
|
||||||
s += find_max_subnumber(parsed, 2)
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def part_2(input_data: str) -> Any:
|
def part_2(input_data: str) -> Any:
|
||||||
s = 0
|
return sum(_find_max_subnumber(p, 12) for p in _parse_input(input_data))
|
||||||
for line in input_data.splitlines():
|
|
||||||
parsed = list(map(int, line))
|
|
||||||
s += find_max_subnumber(parsed, 12)
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def test_find_max_subnumber():
|
def test_find_max_subnumber():
|
||||||
assert find_max_subnumber([1, 2, 3, 4, 9], 2) == 49
|
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([1, 2, 3, 4, 5], 2) == 45
|
||||||
assert find_max_subnumber([5, 4, 3, 2, 1], 2) == 54
|
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([1, 3, 5, 2, 4], 2) == 54
|
||||||
assert find_max_subnumber([8, 1, 8, 2, 7, 3], 3) == 887
|
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, 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, 5], 3) == 345
|
||||||
|
|
||||||
|
|
||||||
def test_part_1(example_data):
|
def test_part_1(example_data):
|
||||||
|
|||||||
Reference in New Issue
Block a user