82 lines
2.2 KiB
Python
82 lines
2.2 KiB
Python
"""
|
||
It was proposed by Christian Goldbach that every odd composite number can be written as the sum of a prime and twice a square.
|
||
|
||
9 = 7 + 2 * 1^2
|
||
15 = 7 + 2 * 2^2
|
||
21 = 3 + 2 * 3^2
|
||
25 = 7 + 2 * 3^2
|
||
27 = 19 + 2 * 2^2
|
||
33 = 31 + 2 * 1^2
|
||
|
||
It turns out that the conjecture was false.
|
||
What is the smallest odd composite that cannot be written as the sum of a prime and twice a square?
|
||
"""
|
||
|
||
import math
|
||
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 sieve_of_eratosthenes(limit: int = 5000) -> list[bool]:
|
||
"""生成一个布尔数组,is_prime[i]为True表示i是质数"""
|
||
is_prime = [True] * (limit + 1)
|
||
is_prime[0:2] = [False, False]
|
||
|
||
for i in range(2, int(limit**0.5) + 1):
|
||
if is_prime[i]:
|
||
for j in range(i * i, limit + 1, i):
|
||
is_prime[j] = False
|
||
return is_prime
|
||
|
||
|
||
def optimized_find_counterexamples(limit: int = 10000) -> list[int]:
|
||
"""
|
||
优化版本,使用集合提高查找效率
|
||
"""
|
||
# 生成质数表
|
||
is_prime = sieve_of_eratosthenes(limit)
|
||
primes = [i for i in range(limit + 1) if is_prime[i]]
|
||
|
||
# 预计算所有奇合数
|
||
odd_composites = set(n for n in range(3, limit + 1, 2) if not is_prime[n])
|
||
|
||
# 预计算2k²的值
|
||
max_k = int(math.sqrt(limit / 2)) + 1
|
||
two_k_squared = [2 * k * k for k in range(1, max_k + 1)]
|
||
|
||
# 计算所有可以表示的奇合数
|
||
representable_odd_composites = set()
|
||
for p in primes:
|
||
if p > limit:
|
||
break
|
||
for tks in two_k_squared:
|
||
n = p + tks
|
||
if n > limit:
|
||
break
|
||
if n in odd_composites:
|
||
representable_odd_composites.add(n)
|
||
|
||
# 找出不能表示的奇合数
|
||
return sorted(odd_composites - representable_odd_composites)
|
||
|
||
|
||
@timer
|
||
def main(limit: int = 20000) -> None:
|
||
res = optimized_find_counterexamples(limit)
|
||
for r in res:
|
||
print(r)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|