金蝉素数

问题描述:

某古寺的一块石碑上依稀刻有一些神秘的自然数。
专家研究发现:这些数是由1,3,5,7,9这5个奇数字排列组成的5位素数,同时去掉它的最高位与最低位数字后的3位数还是素数,同时去掉它的高二位与低二位数字后的一位数还是素数。因此人们把这些神秘的素数称为金蝉素数,喻意金蝉脱壳之后仍为美丽的金蝉。
试求出石碑上的金蝉素数。

注意:

它这里说的高二位与低二位数字后的一位数应该是去掉高位和低位的第二个后的三位数,不应该是一位数;


我的代码:

import math
import itertools
def prime(x):
    count=0
    for i in range(2,int(math.sqrt(x))+1):
        if x%i==0:
            count=1
    if count==0:
        return True
    else:
        return False
c=[]
for j in itertools.permutations([1,3,5,7,9],5):
    c.append(j)
for k in range(len(c)):
    l=c[k][0]*10000+c[k][1]*1000+c[k][2]*100+c[k][3]*10+c[k][4]
    m=c[k][1]*100+c[k][2]*10+c[k][3]
    n=c[k][0]*100++c[k][2]*10++c[k][4]
    if prime(l)==True and prime(m)==True and prime(n)==True:
      print l,


结果:

13597 15937 51973 53791 79531 91573


我的思路:

首先定义了一个prime函数,该函数判断传入的数是否为素数,然后根据itertools的permutations函数返回长度为5的所有的由1,3,5,7,9组成的不重复数放入列表中,其格式为[(1,3,5,7,9),(1,3,5,9,7)....],然后判断列表中每一个值是否满足原数,原数去掉最高位与最低位数字后的3位数和原数去掉高二位与低二位数字后的三位数同时都是素数,满足的话就是金蝉素数;


示例代码:

# 1. 生成 1,3,5,7,9 全排列, 每种排列是一个元组
# 2. 元组转换成数字 (例: 13579,357,159)
# 3. 检测3个数字是素数,如全是素数则是金蝉数

import math
def isPrimeNum(n):
    for k in range(2, int(math.sqrt(n) + 1)):
        if n % k == 0:
            return False
    return True

from itertools import permutations
for p in permutations([1,3,5,7,9], 5):
    # (3,5,7), (1,5,9), (1,3,5,7,9)
    for l in (p[1:-1], p[::2], p):
        s = reduce(lambda x, y: 10 * x + y, l)
        if not isPrimeNum(s):
            break
    else:
        print p


代码分析:

示例代码和我的大致相同,只不过它循环得到元组后又直接循环p[1:-1], p[::2], p即原数去掉最高位与最低位数字后的3位数,原数去掉高二位与低二位数字后的三位数和原数所组成的元组,而且我的是通过算术运算将元组转换为数字,而它的是使用reduce函数实现的;


总结:

itertools模块的permutations方法


语法格式:permutations(iterable [,r]):


创建一个迭代器,返回iterable中所有长度为r的项目序列,如果省略了r,那么序列的长度与iterable中的项目数量相同,它对数字进行全排列操作的效率比递归方式要好得多;


关于itertools模块可以参考这篇文章:http://www.cnblogs.com/cython/articles/2169009.html


题目出处:http://www.cheemoedu.com/exercise/21

转载于:https://my.oschina.net/jmbzs/blog/711986

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值