Files
Sidney Zhang e5868c2649 feat(0046.GoldbachsConjecture):添加欧拉项目第46题解决方案
📝 docs(0046.GoldbachsConjecture):添加问题描述和解题思路说明
2026-02-03 14:35:55 +08:00

82 lines
2.2 KiB
Python
Raw Permalink 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.

"""
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()