鱼C论坛

 找回密码
 立即注册
查看: 2635|回复: 6

[技术交流] 小练习:20160919 找出所有11个可以双向裁剪的质数

[复制链接]
发表于 2016-9-19 11:04:30 | 显示全部楼层 |阅读模式

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

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

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

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


                               
登录/注册后可看大图

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




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

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

----回帖需写明解题思路,鼓励在程序中加上注释-----
----除列出程序外,请给出输出的结果。----




题目:

3797 这个数很有趣。它本身是质数,而且如果我们从左边不断地裁去数字,得到的仍然都是质数:3797, 797, 97, 7。而且我们还可以从右向左裁剪:3797, 379, 37, 3,得到的仍然都是质数。

找出全部 11 个这样从左向右和从右向左都可以裁剪的质数。

注意:2, 3, 5 和 7 不被认为是可裁剪的质数。

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-9-19 12:35:24 | 显示全部楼层
好棒
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-9-20 17:07:23 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2016-9-25 05:05 编辑

这题思路从数的构成开始,若要满足条件,则:
1. 第1位必然由2,3,5,7组成
2.除第1及最后1位的中间数由1,3,7,9组成
3.最后1位由3,7组成
按照各种排列组合,然后筛选结果。
最后得到:23,37,73,53,313,373,317,797,3137,3797,739397正好11个数。
程序回去再贴。

  1. def isPrime(num):
  2.         flag = 1
  3.         if num == 2 or num == 3:
  4.                 return 1
  5.         elif num % 2 == 0:
  6.                 return 0
  7.         else:
  8.                 for i in range(3,int(num**0.5+1),2):
  9.                         if num % i == 0:
  10.                                 flag = 0
  11.                                 break
  12.                 return flag

  13. def isCycle(strnum):
  14.         flags = 1
  15.         if isPrime(int(strnum)) == 0:
  16.                 flags = 0
  17.         else:
  18.                 length = len(strnum)
  19.                 for l in range(length):
  20.                         if isPrime(int(strnum[l:])) == 0 or isPrime(int(strnum[:l+1])) == 0:
  21.                                 flags = 0
  22.                                 break
  23.         return flags

  24. lst1 = [2,3,5,7]
  25. lst2 = [1,3,7,9]
  26. lst3 = [3,7]
  27. lst4 = [1,3,7,9]
  28. lst = ['23','37','53','73']
  29. final = []
  30. for x in range(4):
  31.         for y in range(4):
  32.                 lst4.append(lst2[x]*10+lst2[y])
  33. for x in range(4):
  34.         for y in range(4):
  35.                 for z in range(4):
  36.                         lst4.append(lst2[x]*100+lst2[y]*10+lst2[z])
  37. for x in range(4):
  38.         for y in range(4):
  39.                 for z in range(4):
  40.                         for w in range(4):
  41.                                 lst4.append(lst2[x]*1000+lst2[y]*100+lst2[z]*10+lst2[w])
  42. for each in lst4:
  43.         for i in range(4):
  44.                 for j in range(2):
  45.                         lst.append(str(lst1[i])+str(each)+str(lst3[j]))
  46. for eachi in lst:
  47.         if isCycle(eachi):
  48.                 final.append (int(eachi))
  49. final = set(final)
  50. print (final)
复制代码

评分

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

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-21 16:33:04 | 显示全部楼层
  1. from time import time
  2. t=time()
  3. def cut(number):
  4.        temp=10**(len(str(number))-1)
  5.        while temp>1:
  6.               yield  number//temp
  7.               yield number%temp
  8.               temp//=10
  9.        yield 0

  10. li=[0,0]+[1]*999999
  11. primes=[]
  12. for i in range(1000001):
  13.        if li[i]:
  14.               primes.append(i)
  15.               value=i*2
  16.               while(value<=1000000):
  17.                      li[value]=0
  18.                      value+=i
  19. quantity=0
  20. for i in primes[4:]:
  21.        if quantity>10:
  22.               break
  23.        iscut=True
  24.        cuts=cut(i)
  25.        while True:
  26.               cutnumber=next(cuts)
  27.               if cutnumber==0:
  28.                      break
  29.               if cutnumber not in primes:
  30.                      iscut=False
  31.                      break
  32.        if iscut:
  33.               print(i)
  34.               quantity+=1

  35. print(time()-t)
复制代码


最后一个太久了
  1. 23
  2. 37
  3. 53
  4. 73
  5. 313
  6. 317
  7. 373
  8. 797
  9. 3137
  10. 3797
  11. 739397
  12. 72.10999965667725
复制代码

评分

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

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-22 10:50:18 | 显示全部楼层
本帖最后由 老忘 于 2016-9-22 10:53 编辑

先说思路:一个n位的数字(根据要求知n>1),将其为为三段:首1位,中间n-2位,末1位,要满足左右截后都是质数
1、首1位只能是【2,3,5,7】。因为向左截到只有首位时要为质数
2、末位只能是【3,7】。因为向右截到只有末位时,可在【2,3,5,7】中选,但如果不截位时,末位【2,5】的不是质数,所以末位只能是【3,7】
3、中间n-2位只能是【1,3,7,9】。因为向左截时,中间任何一位数都可能变成末位,末位如果是偶数和5时,则不是质数。
4、将上述三段进行排列组合后,再进行截位质数判断。

  1. # -*- coding:Utf-8 -*-
  2. import itertools
  3. import time,math
  4. start = time.clock()

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

  26. def check_all_zishu(ss): # 左右裁去数字进行质数判数
  27.     for i in range(0,len(ss)):
  28.         if isPrime(int(ss[0:i+1])):
  29.             if isPrime(int(ss[len(ss)-i-1:])):
  30.                 pass
  31.             else:
  32.                 return False
  33.         else:
  34.             return False
  35.     return True

  36. list_start=[2,3,5,7] # 首位可能出现的数字
  37. list_end=[3,7] # 末位可能出现的数字

  38. # count记录左右截去后都为质数的数字的个数,m为除去首位和末位的中间部分的位数,并赋初值
  39. count=0
  40. m=0

  41. while 1:
  42.     if count==11: # 如果找到11个,则跳出循环
  43.         break
  44.     else:
  45.         list_mid=[] # list_mid存放中间位数的列表
  46.         for eachone in list(itertools.product(['1','3','7','9'],repeat = m)): # 生成中间位数的列表
  47.             s=''
  48.             for each in eachone:
  49.                 s+=each
  50.             list_mid.append(s)

  51.         # 通过list_start,list_mid,list_end来进行组合
  52.         for int_start in list_start:
  53.             for str_mid in list_mid:
  54.                 for int_end in list_end:
  55.                     aa=str(int_start)+str_mid+str(int_end)
  56.                     if check_all_zishu(aa):
  57.                         count+=1
  58.                         print(aa)
  59.         m+=1

  60. end = time.clock()
  61. print ("read: %f s" % (end - start))
复制代码


计算结果:
  1. 23
  2. 37
  3. 53
  4. 73
  5. 313
  6. 317
  7. 373
  8. 797
  9. 3137
  10. 3797
  11. 739397
  12. read: 0.025948 s
复制代码

评分

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

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-24 09:16:19 | 显示全部楼层
本帖最后由 飘飞的白杨 于 2016-9-24 11:20 编辑
  1. N = 1000000
  2. l =  int(N**0.5) + 1
  3. prime = [False, False] + [True] * N
  4. for i in range(2, l):
  5.     if prime[i]:
  6.         for j in range(2, N//i + 1):
  7.             if prime[j*i]:
  8.                 prime[j*i] = False
  9. m = 0
  10. num = 0
  11. def nnn(n):
  12.     x = [str(n),str(n)]
  13.     while len(x[0]) >= 1 and len(x[1]) >= 1:
  14.         if prime[int(x[0])] and prime[int(x[1])]:
  15.             x = [x[0][:-1],x[1][1:]]
  16.         else:
  17.             return False
  18.     global num,m
  19.     num += n
  20.     m += 1
  21. n = 11
  22. while True:
  23.     if m >= 11:
  24.         break
  25.     nnn(n)
  26.     n += 2
  27. print(num)
复制代码



ps:我能吐槽题目要求中的时间错了吗?

评分

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

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-26 00:11:47 | 显示全部楼层
  1. from time import time
  2. start=time()

  3. zs1=['2','3','7']
  4. zs2=['2','3','5','7']
  5. zs3=[2]
  6. zs0=[]
  7. zs=[]
  8. def zhishu(a):
  9.     sq=a**0.5
  10.     if sq==int(sq):
  11.         return False
  12.     sq=int(sq)

  13.     for x in zs3:
  14.         if x>sq:
  15.             return True
  16.         if a/x==int(a/x):
  17.             return False

  18. for i in range(3,1000000):
  19.     if zhishu(i):
  20.         zs3.append(i)

  21. for i in zs3:
  22.         zs0.append(str(i))

  23. for k in zs0:
  24.     if len(k)==2 and k[:1] in zs0 and k[-1:] in zs0:
  25.         zs.append(int(k))
  26.     elif len(k)==3 and k[:1] in zs0 and k[-1:] in zs0 and k[:2] in zs0 and k[-2:] in zs0:
  27.         zs.append(int(k))
  28.     elif len(k)==4 and k[:1] in zs0 and k[-1:] in zs0 and k[:2] in zs0 and k[-2:] in zs0 and k[:3] in zs0 and k[-3:] in zs0:
  29.         zs.append(int(k))
  30.     elif len(k)==5 and k[:1] in zs0 and k[-1:] in zs0 and k[:2] in zs0 and k[-2:] in zs0 and k[:3] in zs0 and k[-3:] in zs0 and k[:4] in zs0 and k[-4:] in zs0:
  31.         zs.append(int(k))
  32.     elif len(k)==6 and k[:1] in zs0 and k[-1:] in zs0 and k[:2] in zs0 and k[-2:] in zs0 and k[:3] in zs0 and k[-3:] in zs0 and k[:4] in zs0 and k[-4:] in zs0 and k[:5] in zs0 and k[-5:] in zs0:
  33.         zs.append(int(k))
  34. print(zs)
  35. print(time()-start)
  36.                
复制代码

  1. >>> ================================ RESTART ================================
  2. >>>
  3. [23, 37, 53, 73, 313, 317, 373, 797, 3137, 3797, 739397]
  4. 1369.6615242958069
  5. >>>
复制代码

评分

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

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-21 14:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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