鱼C论坛

 找回密码
 立即注册
查看: 3544|回复: 10

[技术交流] 小练习:20160711 找出为连续数字产生最多质数的二次公式

[复制链接]
发表于 2016-7-10 19:53:58 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 冬雪雪冬 于 2016-7-19 19:14 编辑

从现在开始我们要开展一批欧拉计划的习题练习。
其实在我们论坛中已有欧拉计划的板块,可能有些鱼油还没注意到。
什么是欧拉计划:http://bbs.fishc.com/thread-60405-1-1.html
我们欧拉板块现已给出了81道题,这批练习将从欧拉计划中选题。其实用python语言完成有很多的优势,可以更简洁更方便的实现。
如果大家有兴趣也可浏览欧拉的英文网站:https://projecteuler.net/archives
这里已经有了500余题。


                               
登录/注册后可看大图

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




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

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

----除列出程序外,请给出输出的结果。----


题目:

欧拉曾发表过一个著名的二次公式:


                               
登录/注册后可看大图


这个公式对于0到39的连续数字能够产生 40 个质数。但是当 n = 40 时,

                               
登录/注册后可看大图
能够被 41 整除。当 n = 41 时,

                               
登录/注册后可看大图
显然也能被 41 整除。

利用计算机,人们发现了一个惊人的公式:

                               
登录/注册后可看大图
。这个公式对于 n = 0 到 79 能够产生 80 个质数。这个公式的系数,−79 和 1601 的乘积是 −126479。

考虑如下形式的二次公式:


                               
登录/注册后可看大图


其中 |n| 表示 n 的绝对值。

例如, |11| = 11, |−4| = 4

对于能够为从 0 开始的连续的 n 产生最多数量的质数的二次公式,找出该公式的系数a, b和它们的乘积。



我试了一下,大约用时6s多,看看大家有什么巧妙的方法。


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

本帖被以下淘专辑推荐:

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

使用道具 举报

 楼主| 发表于 2016-7-10 19:54:22 | 显示全部楼层
  1. import math
  2. def iscomposit(n):
  3.     for i in range(2, int(math.sqrt(n)) + 1):
  4.         if n % i == 0:
  5.             return True
  6.     return False

  7. maxprime = 0
  8. for a in range(-999, 1000):
  9.     for b in range(-999, 1000):
  10.         n = 0
  11.         while True:
  12.             x = n * n  + a * n + b
  13.             if x < 2 or iscomposit(x):
  14.                 break
  15.             n += 1
  16.         if maxprime < n:
  17.             maxprime = n
  18.             maxa = a
  19.             maxb = b
  20. print('a= %d, b = %d, a * b = %d'%(maxa, maxb, maxa *maxb))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-7-11 01:50:10 | 显示全部楼层
考虑 n=0时多项式结果为质数可知c是1000以内的质数
考虑 n=1时,可得1+b+c为质数,因此b>-c,而且b应为奇数(排除质数为2的情况,因为当n=2时多项式因为正数)
  1. def primes_sieve(limit):
  2.     limitn,not_prime,primes = limit+1,set(),list()
  3.     for i in range(2, limitn):
  4.         if i in not_prime:
  5.             continue
  6.         for f in range(i*2, limitn, i):
  7.             not_prime.add(f)
  8.         primes.append(i)
  9.     return primes
  10.    

  11. import time

  12. t,maxi,prime_l = time.time(),0,list(reversed(primes_sieve(1000)))   
  13. prime_s = set(primes_sieve(10000))

  14. for c in prime_l:
  15.     for b in range(-c+2,1000,2):
  16.         for i in range(1,100):
  17.             if (i**2 + b*i + c) not in prime_s:
  18.                 if i > maxi:
  19.                     maxi,result = i,b*c
  20.                 break
  21.             

  22. print('time:',time.time()-t,'result:',result)
复制代码

在我的机器上(i5-3210M):
time: 0.23101305961608887 result: -59231

评分

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

查看全部评分

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

使用道具 举报

发表于 2016-7-11 09:52:44 | 显示全部楼层
本帖最后由 mather 于 2016-7-11 09:55 编辑
  1. import time
  2. on = time.time()


  3. from math import sqrt
  4. def is_prime(num):
  5.     if num<=1:
  6.         return False
  7.     t = 2
  8.     res = True
  9.     while t <= sqrt(num):
  10.         if num%t==0:
  11.             res = False
  12.             break
  13.         else:
  14.             t += 1
  15.     return res

  16. max_primes = 41#要利用上已知的条件
  17. res_a_b = 1,41

  18. for a in range(-999,1000,2):#如果要1+a+b是质数,b是质数的前提下,a必然是奇数
  19.     for b in range(2,1000):#b只能从2开始取,且b只能是质数
  20.         if not is_prime(b):#如果b不是质数下一个
  21.             continue
  22.         elif b<max_primes:#如果比最多的个数值小下一个
  23.             continue
  24.         elif a<0 and not is_prime((max_primes-1+a)*(max_primes-1)+b):#在a是负数的时候很容易产生负数值,所以过滤一下
  25.             continue
  26.         else:
  27.             for j in range(b):#最多从0到b-1,b个质数
  28.                 if not is_prime((j+a)*j+b):#验证j是不是质数,如果是下一个
  29.                     break
  30.             if j > max_primes:#找到更大的,记录一下
  31.                 max_primes = j
  32.                 res_a_b = a,b
  33. print("最多个数的系数组合是a=%d,b=%d,乘积是%d" % res_a_b,res_a_b[0]*res_a_b[1])

  34. print(time.time()-on)
复制代码

结果:最多个数的系数组合是a=-61,b=971,乘积是 -59231
运行时间:4.0335609912872314

评分

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

查看全部评分

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

使用道具 举报

发表于 2016-7-11 13:41:06 | 显示全部楼层
本帖最后由 bacon6581 于 2016-7-11 13:43 编辑
  1. from time import time
  2. start=time()

  3. def zhishu(n):
  4.     if n==2:
  5.         return True
  6.     if n**0.5==int(n**0.5):
  7.         return False
  8.     m=int(n**0.5)
  9.     for i in range(2,m+1):
  10.         if n%i==0:
  11.             return False
  12.     return True

  13. a_result=0
  14. b_result=0
  15. x_max=0

  16. a=-1001
  17. while a<=1000:
  18.     a+=1
  19.     b=-1001

  20.     while b<=1000:
  21.         b+=1

  22.         x=-1
  23.         while 1:
  24.             x+=1
  25.             if x*x + a*x +b<=2:
  26.                 break
  27.             if zhishu(x*x + a*x +b)==False:
  28.                 break

  29.         if x>x_max:
  30.             x_max=x
  31.             a_result=a
  32.             b_result=b
  33. print('a*b is: ',a_result*b_result)
  34. print('a is: ',a_result,'b is: ',b_result)
  35. print('Used time: ',time()-start)
复制代码


无标题.jpg

评分

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

查看全部评分

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

使用道具 举报

发表于 2016-7-12 00:14:20 | 显示全部楼层
本帖最后由 huomqh 于 2016-7-12 15:00 编辑
  1. def isPrime(x):
  2.     i=2
  3.     if x<=1:
  4.         return 0
  5.    
  6.     while i**2<=x:
  7.         if x%i==0:
  8.             return 0
  9.         i+=1
  10.     return 1

  11. def f(x,y,z):
  12.     return x*x+y*x+z

  13. def g(x,y):
  14.     if x<0:
  15.         return x*x-4*y
  16.     else:
  17.         return -1
  18.    
  19. import time
  20. tt=time.time()
  21. b=3
  22. count=0
  23. counta=0
  24. countb=0
  25. while b<=999:
  26.     if isPrime(b)==0:
  27.         b+=2
  28.         continue
  29.     a=999
  30.     while (a>=-999) and (g(a,b)<0):
  31.         i=1
  32.         while isPrime(f(i,a,b))==1:
  33.             i+=1
  34.         if i-1>count:
  35.             count,counta,countb=i-1,a,b
  36.         a-=2
  37.     b+=2

  38. print('a=%d,b=%d,a*b=%d,n=%d'%(counta,countb,counta*countb,count))
  39. print('用时:%.4f s'%(time.time() - tt))
复制代码


结果:
  1. a=-61,b=971,a*b=-59231,n=70
  2. 用时:1.3211 s
复制代码

评分

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

查看全部评分

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

使用道具 举报

发表于 2016-7-12 18:13:43 | 显示全部楼层
本帖最后由 Spicebush 于 2016-7-13 07:55 编辑
  1. #答案为a = -61, b = 971, a * b = -59231
  2. import math
  3. def zs(n):
  4.     if n>0:
  5.         half=math.sqrt(n)
  6.         for i in range(2,int(math.sqrt(n))+1):
  7.             if n%i==0:
  8.                 return False
  9.                 break
  10.         return True
  11.     else:
  12.         return False

  13. js_l = [x for x in range(-999, 1000) if x%2 != 0]
  14. zs_l = [x for x in range(-999, 1000) if zs(abs(x))]

  15. z = 1
  16. for a in js_l:
  17.     for b in zs_l:
  18.         n = 1
  19.         while zs(n*n + a*n + b):
  20.             n += 1
  21.         if n > z:
  22.             z, A, B = n, a, b
  23.             
  24. print('a =', A, '\nb =', B, '\na * b =', A*B)
复制代码

评分

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

查看全部评分

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

使用道具 举报

发表于 2016-7-15 11:16:12 | 显示全部楼层
a为-61,b为971,乘积为-59231
  1. import math
  2. import time

  3. st = time.time()

  4. jishu = []
  5. fujishu = []
  6. zhishua = []
  7. zuida = 40
  8. zuidaa = 1
  9. zuidab = 41

  10. def zspd(n):
  11.     if n <= 1:
  12.         return False
  13.     y = int(math.sqrt(n))
  14.     for i in range(2,y+1):
  15.         if n % i == 0:
  16.             return False
  17.     return True

  18. for i in range(999,1,-1):
  19.     if zspd(i):
  20.         zhishua.append(i)

  21. for i in range(1,1000):
  22.     if i % 2 != 0:
  23.         jishu.append(i)
  24.         
  25. for i in jishu:
  26.     fujishu.append(-i)

  27. fanweia = fujishu + jishu

  28. for a in fanweia:
  29.     for b in zhishua:
  30.         if zspd(zuida*zuida + a*zuida +b):
  31.             n = 1
  32.             x = a+b+1
  33.             while zspd(x):
  34.                 x += (2 * n + 1 + a)
  35.                 n += 1
  36.             if n>zuida:
  37.                 zuida = n
  38.                 zuidaa = a
  39.                 zuidab = b
  40.         else:
  41.             next

  42. cj = zuidaa * zuidab                  
  43. print("a为%d,b为%d" % (zuidaa,zuidab))
  44. print("乘积为%d" % cj)
  45. leng = time.time() - st
  46. print("用时%f" % leng)
复制代码

评分

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

查看全部评分

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

使用道具 举报

发表于 2016-7-15 17:36:00 | 显示全部楼层
应该是20160711 吧???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-19 19:15:40 | 显示全部楼层
无符号整形 发表于 2016-7-15 17:36
应该是20160711 吧???

晕!犯了个低级错误。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2016-7-22 04:15:00 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-27 00:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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