问题描述:

某古寺的一块石碑上依稀刻有一些神秘的自然数。
专家研究发现:这些数是由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