feat: 添加欧拉项目第56题解法(最大数字和)
添加 `euler_56.py` 实现计算 a^b 形式自然数的最大数字和,包含基准测试装饰器和两种算法实现
This commit is contained in:
77
solutions/0056.PowerfulDigitSum/euler_56.py
Normal file
77
solutions/0056.PowerfulDigitSum/euler_56.py
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
"""
|
||||||
|
A googol (10^100) is a massive number: one followed by one-hundred zeros;
|
||||||
|
100^100 is almost unimaginably large: one followed by two-hundred zeros.
|
||||||
|
Despite their size, the sum of the digits in each number is only 1 .
|
||||||
|
|
||||||
|
Considering natural numbers of the form, a^b , where a,b < 100 , what is the maximum digital sum?
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
from decimal import MAX_EMAX
|
||||||
|
from functools import wraps
|
||||||
|
from typing import Any, Callable, TypeVar
|
||||||
|
|
||||||
|
F = TypeVar("F", bound=Callable[..., Any])
|
||||||
|
|
||||||
|
|
||||||
|
def benchmark(repeat: int = 1) -> Callable[[F], F]:
|
||||||
|
if repeat < 1:
|
||||||
|
raise ValueError("repeat must >= 1")
|
||||||
|
|
||||||
|
def decorator(func: F) -> F:
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||||
|
total = 0.0
|
||||||
|
result = None
|
||||||
|
|
||||||
|
for _ in range(repeat):
|
||||||
|
start = time.perf_counter()
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
end = time.perf_counter()
|
||||||
|
total += end - start
|
||||||
|
|
||||||
|
wrapper.avg_time = total / repeat # type: ignore[attr-defined]
|
||||||
|
wrapper.total_time = total # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"[Benchmark] {func.__name__} | repeated {repeat} times | "
|
||||||
|
f"average: {wrapper.avg_time:.6f}s | total: {wrapper.total_time:.6f}s" # type: ignore[attr-defined]
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
wrapper.avg_time = 0.0 # type: ignore[attr-defined]
|
||||||
|
wrapper.total_time = 0.0 # type: ignore[attr-defined]
|
||||||
|
return wrapper # type: ignore[return-value]
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def powtodigit(a: int, b: int) -> tuple[int, str]:
|
||||||
|
res = pow(a, b)
|
||||||
|
return res, str(res)
|
||||||
|
|
||||||
|
|
||||||
|
@benchmark(repeat=15)
|
||||||
|
def main() -> None:
|
||||||
|
max_digit_sum = 0
|
||||||
|
for a in range(2, 101):
|
||||||
|
for b in range(2, 101):
|
||||||
|
digit_sum = sum(int(d) for d in powtodigit(a, b)[1])
|
||||||
|
max_digit_sum = max(max_digit_sum, digit_sum)
|
||||||
|
print(f"Maximum digit sum: {max_digit_sum}")
|
||||||
|
|
||||||
|
|
||||||
|
@benchmark(repeat=15)
|
||||||
|
def main_inone() -> None:
|
||||||
|
max_digit_sum = 0
|
||||||
|
abp = 1
|
||||||
|
a = 99
|
||||||
|
for b in range(100, 2, -1):
|
||||||
|
abp = abp * a
|
||||||
|
max_digit_sum = max(max_digit_sum, sum(int(d) for d in str(abp)))
|
||||||
|
print(f"Maximum digit sum: {max_digit_sum}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
main_inone()
|
||||||
Reference in New Issue
Block a user