81 lines
1.8 KiB
Python
81 lines
1.8 KiB
Python
"""
|
||
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()
|