feat(0052): 添加欧拉52题“排列倍数”的最优算法实现

This commit is contained in:
2026-03-23 11:12:24 +08:00
parent be30320454
commit 17064cf38c
2 changed files with 147 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
"""
It can be seen that the number, 125874, and its double, 251748,
contain exactly the same digits, but in a different order.
Find the smallest positive integer, x, such that
2x, 3x, 4x, 5x, and 6x contain the same digits.
"""
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
elapsed_time = end_time - start_time
print(f"{func.__name__} time: {elapsed_time:.6f} seconds")
return result
return wrapper
def has_same_digits(x, y):
return sorted(str(x)) == sorted(str(y))
def signature(n):
count = [0] * 10
while n:
count[n % 10] += 1
n //= 10
return tuple(count)
def find_smallest_permuted_multiple():
x = 1
while True:
if not x % 9 == 0:
x += 1
continue
for i in range(2, 7):
if not has_same_digits(x, x * i):
break
else:
return x
x += 1
def better_permuted_multiple():
n = 1
while True:
start = 10 ** (n - 1)
# 核心约束x * 6 必须仍是n位数
end = int(10**n / 6) + 1
# 步长为9利用模9同余原理
for x in range((start + 8) // 9 * 9, end, 9):
sig = signature(x)
# 检查2x到6x是否共享相同签名
if all(signature(k * x) == sig for k in range(2, 7)):
return x
n += 1
@timer
def main():
result = find_smallest_permuted_multiple()
print(f"{result}")
@timer
def main_better():
result = better_permuted_multiple()
print(f"{result}")
if __name__ == "__main__":
main()
main_better()