Files
SolutionEuler/solutions/0000_0029/0029.DistinctPowers/euler_29.py
2025-12-26 17:35:14 +08:00

93 lines
2.5 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.

"""
Consider all integer combinations of a^b for 2<=a<=5 and 2<=b<=5 :
2^2 = 4 2^3 = 8 2^4 = 16 2^5 = 32
3^2 = 9 3^3 = 27 3^4 = 81 3^5 = 243
4^2 = 16 4^3 = 64 4^4 = 256 4^5 = 1024
5^2 = 25 5^3 = 125 5^4 = 625 5^5 = 3125
If they are then placed in numerical order, with any repeats removed,
we get the following sequence of 15 distinct terms:
4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125
How many distinct terms are in the sequence generated by a^b for 2<=a<=100 and 2<=b<=100 ?
"""
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__} runtime: {end_time - start_time} seconds")
return result
return wrapper
def count_distinct_terms_efficient(limit_a, limit_b):
# 预计算每个 a 的最小底数表示
base_map = {}
power_map = {}
for a in range(2, limit_a + 1):
base_map[a] = a
power_map[a] = 1
# 找出所有可以表示为幂的数
for power in range(2, 7): # 2^7=128>100所以最多到6次幂
base = 2
while base**power <= limit_a:
value = base**power
# 如果这个值还没有被更小的底数表示
if base_map[value] == value:
base_map[value] = base
power_map[value] = power
base += 1
# 使用集合存储 (base, exponent) 对
seen = set()
for a in range(2, limit_a + 1):
base = base_map[a]
power = power_map[a]
# 如果 a 是某个数的幂,我们需要检查 base 是否还能分解
# 例如16 = 4^2但 4 = 2^2所以 16 = 2^4
# 我们需要找到最终的 base
while base_map[base] != base:
power = power * power_map[base]
base = base_map[base]
for b in range(2, limit_b + 1):
seen.add((base, power * b))
return len(seen)
def do_compute(a_top: int, b_top: int, a_down: int = 2, b_down: int = 2) -> int:
tmp = set()
for a in range(a_down, a_top + 1):
for b in range(b_down, b_top + 1):
tmp.add(a**b)
return len(tmp)
@timer
def main():
"""not bad"""
print(count_distinct_terms_efficient(100, 100))
@timer
def main2():
print(do_compute(100, 100))
if __name__ == "__main__":
main()
main2()