Files
SolutionEuler/solutions/0005.smallestMultiple/eular_5.py
Sidney Zhang 7df59c9bcf feat(eular_5.py):添加计时装饰器和Python内置lcm解决方案
📝 docs(eular_5.py):增加性能测试功能,比较两种实现方式的执行时间
2025-12-15 15:19:14 +08:00

88 lines
1.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
"""
import math
import random
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} took {end_time - start_time:.6f} seconds")
return result
return wrapper
def is_probable_prime(n: int, trials: int = 10) -> bool:
"""Miller-Rabin素性测试快速判断是否为质数"""
if n < 2:
return False
if n in (2, 3):
return True
if n % 2 == 0:
return False
# 将 n-1 写成 d * 2^s 的形式
d = n - 1
s = 0
while d % 2 == 0:
d //= 2
s += 1
# 测试
for _ in range(trials):
a = random.randrange(2, n - 1)
x = pow(a, d, n)
if x == 1 or x == n - 1:
continue
for _ in range(s - 1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True
def primes_up_to(n: int) -> list[int]:
if n < 2:
return []
if n == 2:
return [2]
if n == 3:
return [2, 3]
primes = [2, 3]
for i in range(5, n + 1, 2):
if is_probable_prime(i):
primes.append(i)
return primes
@timer
def smallest_multiple(n: int) -> int:
result = 1
for p in primes_up_to(n):
# 找出最大幂次
exp = int(math.log(n, p))
result *= p**exp
return result
@timer
def python_solution(n: int) -> int:
ls = list(range(1, n + 1))
return math.lcm(*ls)
if __name__ == "__main__":
print(smallest_multiple(20))
print(python_solution(20))