✨ feat(0046.GoldbachsConjecture):添加欧拉项目第46题解决方案
📝 docs(0046.GoldbachsConjecture):添加问题描述和解题思路说明
This commit is contained in:
81
solutions/0046.GoldbachsConjecture/euler_46.py
Normal file
81
solutions/0046.GoldbachsConjecture/euler_46.py
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
"""
|
||||||
|
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()
|
||||||
4
solutions/0046.GoldbachsConjecture/readme.md
Normal file
4
solutions/0046.GoldbachsConjecture/readme.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
这个问题,怎么都不算有简洁的方式找到,暴力搜索是唯一途径,但所幸,这个搜索还算快速。
|
||||||
|
|
||||||
|
另外,这个问题可以在 [OEIS](https://oeis.org/A060003) 上直接搜索到。
|
||||||
|
这也算是最简单偷懒的方式了吧。
|
||||||
Reference in New Issue
Block a user