鱼C论坛

 找回密码
 立即注册
查看: 5143|回复: 27

[技术交流] 小练习:20160418 计算两百万以下所有质数的和

[复制链接]
发表于 2016-4-18 10:00:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 冬雪雪冬 于 2016-4-26 11:20 编辑

从现在开始我们要开展一批欧拉计划的习题练习。
其实在我们论坛中已有欧拉计划的板块,可能有些鱼油还没注意到。
什么是欧拉计划:http://bbs.fishc.com/thread-60405-1-1.html
我们欧拉板块现已给出了81道题,这批练习将从欧拉计划中选题。其实用python语言完成有很多的优势,可以更简洁更方便的实现。
如果大家有兴趣也可浏览欧拉的英文网站:https://projecteuler.net/archives
这里已经有了500余题,并且你每做对一题,就可以下载到参考答案的pdf文件,看看你的实现方法与参考答案有什么不同,以利于迅速提高自己的水平。


                               
登录/注册后可看大图

好了言归正传,我们开始做小练习。




题目要求:
以python语言完成,如果是python2请注明。
程序以代码文字格式发帖。
题目比较简单,注重程序效率和创意。
答题在4.26 10:00前完成,其后将公开大家的答案,并评比成绩。

另程序和答案可以在网上搜到,希望大家独立完成。


题目:

10 以下的质数的和是 2 + 3 + 5 + 7 = 17.

找出两百万以下所有质数的和。


奖励:
对所有完成程序并得出正确答案的将给予加分奖励,优秀的将额外加分。
在完成一批题目后,将根据每期的完成情况总评评出最佳,会有神秘大奖。

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-4-18 13:16:35 | 显示全部楼层
本帖最后由 holdme 于 2016-4-18 16:37 编辑

先占个座,效率不高
  1. import time
  2. import functools
  3. start = time.clock()
  4. from math import sqrt; from itertools import count, islice

  5. def isPrime(n):
  6.     return n > 1 and all(n%i for i in islice(count(2), int(sqrt(n)-1)))


  7. num_list = (2,) + tuple(range(3,2000000,2))
  8. sum_p = functools.reduce(lambda x,y:x+y, (y for y in num_list if isPrime(y)))
  9. print(sum_p)
  10. print('%s'%(time.clock()-start))
复制代码


结果是:
  1. 2148933
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-18 14:21:32 | 显示全部楼层
  1. list1 = [2]
  2. summation = 2
  3. for i in range(3,2000000,2):
  4.     for j in list1:
  5.         quotient = i // j
  6.         remainder = i % j
  7.         if remainder == 0:
  8.             break
  9.         elif quotient < j:
  10.             summation += i
  11.             list1.append(i)
  12.             break

  13. print(summation)
复制代码


= = 不会优化了  200W好大。

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-18 16:48:52 | 显示全部楼层
本帖最后由 dvdvdv 于 2016-4-18 21:41 编辑

print (sum([i for i in range(1, 2000001) if not [j for j in range(2, i // 2 +1) if i % j == 0]]))
结果:142913828922

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-18 17:31:26 | 显示全部楼层
本帖最后由 挥舞乾坤 于 2016-4-18 19:08 编辑

python风格版:
  1. prime = lambda max=2000000:sum((x for x in range(3,max,2) if all(x % y for y in range(3,int(x**.5)+1))))+2
  2. print(prime())
复制代码

纯循环版:
  1. def prime(max=2000000):
  2.     sum = 2
  3.     for n in range(3,max+1,2):
  4.         for i in range(3, int(n**.5)+1):
  5.             if n % i == 0:
  6.                 break
  7.         else:
  8.             sum += n
  9.     return sum
  10. print(prime())
复制代码

最好理解的版本:
  1. def prime(max=2000000):

  2.     def isprime(num): #判断是不是质数
  3.         for i in range(3,int(num**.5)+1):
  4.             if num % i == 0:
  5.                 return False
  6.         return True

  7.     sum = 2
  8.     for n in range(3,max+1,2):#质数肯定是奇数(当然除了2意外)
  9.         if isprime(n):
  10.             sum += n

  11.     return sum
  12.    
  13. print(prime())
复制代码

再来一个类的版本:
  1. class Prime:
  2.     def __init__(self,max=2000000):
  3.         self.max = max
  4.         self.first = True
  5.         self.nums = iter(range(3, max+1, 2))

  6.     def __next__(self):
  7.         if self.first:
  8.             self.first = False
  9.             return 2
  10.         
  11.         while True:
  12.             i = next(self.nums)
  13.             if all(i % j for j in range(3, int(i**.5)+1)):
  14.                 return i
  15.             
  16.     def __iter__(self):
  17.         return self
  18.    
  19.     def sum(self):
  20.         return sum(self)

  21. print(Prime().sum())
复制代码

点评

很用心的写了多个程序,大赞!  发表于 2016-4-26 20:56

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-18 19:25:14 | 显示全部楼层
严重支持
  1. import math

  2. def primeTest(num):
  3.     for i in range(2, int(math.sqrt(num))+1):
  4.         if num%i==0:
  5.             return False
  6.     return True

  7. def primeSum(n):
  8.     result = 2
  9.     if n < 3:
  10.         return result - 2
  11.     if n == 3:
  12.         return result
  13.     i = 3
  14.     while i < n:
  15.         if primeTest(i):
  16.             result += i
  17.         i += 2
  18.     return result

  19. print(primeSum(2000000))
复制代码

运行结果
  1. >>>
  2. 142913828922
  3. >>>
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-18 22:02:04 | 显示全部楼层
本帖最后由 小火木 于 2016-4-18 22:07 编辑
  1. def primesum(n):
  2.     import math
  3.     lis1=[2]
  4.     nem=3
  5.     while nem<=n:
  6.         val=1
  7.         for i in lis1:
  8.             if i >math.sqrt (nem):
  9.                 break
  10.             elif nem%i==0:
  11.                 val=0
  12.                 break
  13.         if val:
  14.             lis1.append(nem)

  15.         nem+=2
  16.     print(sum(lis1))


  17. import time
  18. t1=time.clock()
  19. primesum(2000000)
  20. t2=time.clock ()
  21. print(t2-t1)
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-18 22:59:23 | 显示全部楼层
  1. def sumPrime(upLimte):
  2.     num = list(range(2, upLimte+1))
  3.     # 去掉偶数
  4.     for k in range(2, int(upLimte/2)+1):
  5.         num[2*k-2] = 0

  6.     for i in range(1, len(num)):
  7.         if num[i] != 0:
  8.             for k in range(3, int(upLimte/num[i])+1, 2):
  9.                 num[num[i]*k-2] = 0
  10.     return sum(num)

  11. if __name__ == '__main__':
  12.     print(sumPrime(2000000))
复制代码

评分

参与人数 1荣誉 +7 鱼币 +7 收起 理由
冬雪雪冬 + 7 + 7 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-19 08:58:55 | 显示全部楼层
  1. import math
  2. def isPrime(n):
  3.     if n <= 1:
  4.         return False
  5.     for i in range(2,int(math.sqrt(n)) + 1):
  6.         if n % i == 0:
  7.             return False
  8.     return True
  9. n=2
  10. s=0
  11. while n <= 2000000:
  12.     if isPrime(n):
  13.         s += n
  14.     n += 1
  15. print('2000000以下的质数的和是%d' % s)
复制代码

  1. 2000000以下的质数的和是142913828922
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-19 09:12:27 | 显示全部楼层
  1. # -*- coding: utf-8 -*-
  2. import math

  3. def isPrime(n):#质数判断
  4.         if n == 1:
  5.                 return False
  6.         elif n < 4:
  7.                 return True
  8.         elif n & 1 == 0:
  9.                 return False
  10.         elif n < 9:
  11.                 return True
  12.         elif n %3 == 0:
  13.                 return False
  14.         else:
  15.                 r = math.floor(math.sqrt(n))
  16.                 f = 5
  17.                 while f <= r:
  18.                         if n % f == 0:
  19.                                 return False
  20.                         if n %(f+2) == 0:
  21.                                 return False
  22.                         f += 6
  23.                 return True

  24. a=2
  25. i=3
  26. while (i<2000001):
  27.     if isPrime(i):a=a+i
  28.     i=i+2
  29. print(a)
复制代码


感觉效率不高,但不知应再如何减少循环了,看来思路是很重要的啊!

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-19 11:04:14 | 显示全部楼层
  1. def a(n):
  2.     a=[1]*(n+1)
  3.     m=2
  4.     su=0
  5.     while m<=n:
  6.         if a[m]:
  7.             su+=m
  8.             l=2*m
  9.             while l<=n:
  10.                 a[l]=0
  11.                 l+=m
  12.         m+=1
  13.     return su
  14. print(a(2000000))
复制代码


结果142913828922

评分

参与人数 2荣誉 +9 鱼币 +9 收起 理由
zooo + 2 + 2 原来数域筛选可以不用判断质数啊...
冬雪雪冬 + 7 + 7 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-4-19 19:44:52 | 显示全部楼层
  1. primes=[2]
  2. for num in range(3,2000000):
  3.         isPrime=True
  4.         for prime in primes:
  5.                 sqr=prime**2
  6.                 if num<sqr:
  7.                         break
  8.                 else:
  9.                         if num%prime==0:
  10.                                 isPrime=False
  11.                                 break
  12.         if isPrime:
  13.                 primes.append(num)
  14. print(sum(primes))
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-20 16:16:50 | 显示全部楼层
本帖最后由 2012277033 于 2016-4-21 11:13 编辑

按照提意,最小的质数是2所以number=2
然后用两个循环来让除数和被除数递进。
用a来判断number的因数,当因数大于2时就跳出一层循环,来减少运算时间
用b来接收质数的值并加起来。
  1. number = 2
  2. num = 1
  3. a = 0
  4. b=0
  5. while number <= 2000000:
  6.     while num <= number:
  7.         if number%num == 0:
  8.             a+=1
  9.         num+=1
  10.         if a>2:
  11.             break
  12.     if a == 2:
  13.         b=b+number
  14.     num=1
  15.     number+=1
  16.     a=0
  17.    
  18. print(b)
复制代码



评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-21 19:21:09 | 显示全部楼层
  1. from math import *

  2. def is_prime(n):
  3.     if n == 2 or n == 3:
  4.         return True
  5.     for num in range(2, int(sqrt(n) + 1)):
  6.         if n % num == 0:
  7.             return False
  8.             break
  9.     return True

  10. def get_prime(num):
  11.     while True:
  12.         if is_prime(num):
  13.             yield num
  14.         num += 1

  15. PRIME = get_prime(2)
  16. sum = 0
  17. for each in PRIME:
  18.     if each < 2000000:
  19.         sum += each
  20.     else:
  21.         break

  22. print(sum)
  23.    
复制代码


运行结果:
  1. 142913828922
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-21 20:04:56 | 显示全部楼层
  1. h = 0
  2. for i in range(2,11): # 200万算了好久,算不出来,2万还行,20万都费劲(T_T)
  3.     c = 0
  4.     for a in range(2,i+1):        
  5.         if( i%a == 0 ):
  6.             c = c + 1
  7.     if(c==1):
  8.         h = h + i
  9. print(h)
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-22 09:54:11 | 显示全部楼层
sum=2   #定义相加的和先为2
b=0       #给判断有没有被1和本身以外的数整除的数一个初值
a=int(input('输入范围:'))      #输入范围
for i in range(3,a+1):          #循环从3开始到范围
    for j in range(2,i):           #循环判断从2到轮到的范围数
        if (i%j==0):                #判断有没有被1和本身以外的数整除
            b=0                       #如果被1和本身以外的数整除,记录0
            break                    #推出循环
        else:                          #再判断
            b=1                      #如果没有被1和本身以外的数整除,记录1
    if b==1:                       #循环结束后判断书不是质数
        sum+=i                   #判断是质数,相加
print(sum)                       #输出相加

代码缺点数目太大运行会很久

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-22 10:33:57 | 显示全部楼层
  1. def is_prime(x):
  2.     flag = True
  3.     sqrt_x = x**(0.5)
  4.     i = 2
  5.     while i<=sqrt_x:
  6.         if x%i==0:
  7.             flag = False
  8.             break
  9.         i += 1
  10.     return flag

  11. a = (2*i+1 for i in range(1,1000000) if is_prime(2*i+1))
  12. print(sum(a)+2)
复制代码

定义个判定质数的方法,然后放到生成器中判定。最后加和引发生成器计算。效率一般,没统计多少秒算出来,大概10s以内吧。
前几天写过一个埃氏筛法,算法思路挺好的,就是运算效率太低了。

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-22 15:22:57 | 显示全部楼层
  1. from math import sqrt

  2. num=2+3+5+7+11

  3. def isprime(n):
  4.     for i in range(2,int(sqrt(n))+1):
  5.         if n % i == 0:
  6.             return False
  7.     return True

  8. for i in range(11,2000000,2):
  9.     if i%3!=0 and i%5!=0 and i%7!=0 and i%11!=0 and isprime(i):
  10.         num=num+i

  11. print(num)
复制代码
能力有限,只能做到这个程度了

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-23 18:05:01 | 显示全部楼层
本帖最后由 zzh-nju 于 2016-4-23 18:07 编辑
  1. from math import *
  2. import time

  3. def is_prime(n):
  4.     if n == 2 or n == 3:
  5.         return True
  6.     if n % 2 == 0:
  7.         return False
  8.     else:
  9.         for num in range(3, int(sqrt(n) + 1), 2):
  10.             if n % num == 0:
  11.                 return False
  12.                 break
  13.         return True

  14. def get_prime(num):
  15.     while True:
  16.         if is_prime(num):
  17.             yield num
  18.         num += 1

  19. t1= time.time()
  20. PRIME = get_prime(2)
  21. sum = 0
  22. for each in PRIME:
  23.     if each < 2000000:
  24.         sum += each
  25.     else:
  26.         break

  27. print(sum)
  28. print(time.time()-t1)  
复制代码


运行结果
  1. 142913828922
  2. 24.587407112121582
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-23 22:21:16 | 显示全部楼层
本帖最后由 loyfee 于 2016-4-23 22:23 编辑
  1. def isPrime(x):
  2.     import math
  3.     return_re = 1   
  4.     if x in (2,3):
  5.         return 1
  6.     elif x >= 4:
  7.         for i in range(2,int(math.sqrt(x))+1):
  8.             if x % i == 0:
  9.                 return_re = 0
  10.         return return_re

  11. def add_Prime(x):
  12.     sum = 2
  13.     for i in range(3,x+1,2):
  14.         if isPrime(i) == 1:
  15.             sum += i
  16.     print(sum)
复制代码


执行:add_Prime(2000000)
第一个模块用于判断是否为素数,第二个函数用于叠加素数,一直到x
计算结果:142913828922
时间用的好长,好像一分钟以上

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-18 14:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表