欧拉计划 50

41这个质数,可以写作6个连续质数之和:

41 = 2 + 3 + 5 + 7 + 11 + 13
这是100以下的最长的和为质数的连续质数序列。

1000以下最长的和为质数的连续质数序列包含21个项,和为953.

找出100万以下的最长的何为质数的连续质数序列之和。

100万以下的哪个质数能够写成最长的连续质数序列?

import math
import time


def is_prime(x):
    """ 是否质数 """
    if x == 1:
        return False
    if x == 2:
        return True
    assert math.floor(x) == x and x > 0
    x_sqrt = int(math.sqrt(x))
    l = [2]
    l.extend(range(3, x_sqrt + 1, 2))
    for i in l:
        if x % i == 0:
            return False
    return True


def get_primes(n):
    """ n以下所有质数集 """
    n_set = set(range(3, n, 2))
    n_set.add(2)
    for i in range(3, n+1, 2):
        if i in n_set:
            i_set = set(range(i * 2, n, i))
            n_set -= i_set
    n_list = list(n_set)
    n_list.sort()
    return n_list     


#t0 = time.time()
#n = 10 ** 6
#prime_list = [2]
#prime_list.extend([i for i in range(3, n, 2) if is_prime(i)])
#max_len = 1
#prime_max_len = 2
#for inx, prime in enumerate(prime_list):
#    # frist
#    for i in range(inx // max_len):
#        primes_sum = 0
#        for j in range(i, inx):
#            primes_sum += prime_list[j]
#            if primes_sum >= prime:
#                break
#        if primes_sum == prime:
#            if j - i + 1 > max_len:
#                max_len = j - i + 1
#                prime_max_len = prime
#print(prime_max_len, max_len)
#t1 = time.time()
#print(t1 - t0)


t0 = time.time()
n = 10 ** 6
prime_list = [2]
prime_list.extend([i for i in range(3, n, 2) if is_prime(i)])
max_len = 1
prime_max_len = 2
for inx, prime in enumerate(prime_list):
    primes_ele = prime_list[0: max_len]
    primes_sum = sum(primes_ele)
    for j in range(max_len, inx):
        primes_ele.append(prime_list[j])
        primes_sum += prime_list[j]
        while primes_sum > prime:
            if len(primes_ele) <= max_len + 1:
                break
            primes_sum -= primes_ele[0]
            primes_ele.pop(0)
        if primes_sum >= prime:
            break
    if primes_sum == prime:
        if len(primes_ele) > max_len:
            max_len = len(primes_ele)
            prime_max_len = prime
print(prime_max_len, max_len)
t1 = time.time()
print(t1 - t0)


t0 = time.time()
n = 10 ** 6
prime_list = get_primes(n)
max_len = 1
prime_max_len = 2
for inx, prime in enumerate(prime_list):
    primes_ele = prime_list[0: max_len]
    primes_sum = sum(primes_ele)
    for j in range(max_len, inx):
        primes_ele.append(prime_list[j])
        primes_sum += prime_list[j]
        while primes_sum > prime:
            if len(primes_ele) <= max_len + 1:
                break
            primes_sum -= primes_ele[0]
            primes_ele.pop(0)
        if primes_sum >= prime:
            break
    if primes_sum == prime:
        if len(primes_ele) > max_len:
            max_len = len(primes_ele)
            prime_max_len = prime
print(prime_max_len, max_len)
t1 = time.time()
print(t1 - t0)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值