题目:
set([7937, 2, 3, 999331, 5, 7, 1931, 13, 17, 131, 919, 919393, 31, 9377, 11939, 37, 113, 93719, 1193, 71, 331999, 3119, 99371, 933199, 311, 391939, 91193, 9311, 19391, 11, 197, 199, 73, 971, 39119, 337, 37199, 19937, 3779, 93911, 939193, 79, 733, 719, 991, 97, 993319, 199933, 7793, 193939, 373, 319993, 393919, 71993, 939391])
55
55
0.297000169754
0.3140001297
55
55
0.302999973297
The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.
There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.
How many circular primes are there below one million?
代码为:#coding=utf-8
import itertools,math,time
def isprime(n):
if not n%2:
return False
for x in xrange(3,min(int(math.sqrt(n))+1,n),2):
if not n%x:
return False
return True
def issuit(n):
nlist=getallnum(n)
for num in nlist:
if not isprime(num):
return -1,nlist
return 0,nlist
def getallnum(n):
n_str=str(n)
relist=set()
for index in xrange(len(n_str)):
relist.add(int(n_str[index:]+n_str[:index]))
return relist
t=time.time()
maxvalue=1000000
reset=set([2])#结果集合
parelist=[-1]*maxvalue#-1表示未读
for num in xrange(3,maxvalue,2):
if parelist[num]==-1:
success,sortset=-2,set([num])
if isprime(num):
success,sortset=issuit(num)#是否是质数,返回的列表
if success==0:
reset.update(sortset)
for tempnum in sortset:#把所有数据元素的数字的倍数置为已读
if tempnum<num:
continue
for x in xrange(tempnum,maxvalue,2*tempnum):
if parelist[x]==-1:
parelist[x]=1
print reset
print len(reset)
print time.time()-t
运行结果为:
set([7937, 2, 3, 999331, 5, 7, 1931, 13, 17, 131, 919, 919393, 31, 9377, 11939, 37, 113, 93719, 1193, 71, 331999, 3119, 99371, 933199, 311, 391939, 91193, 9311, 19391, 11, 197, 199, 73, 971, 39119, 337, 37199, 19937, 3779, 93911, 939193, 79, 733, 719, 991, 97, 993319, 199933, 7793, 193939, 373, 319993, 393919, 71993, 939391])
55
2.36299991608
缺点:
太慢了了,
牛人的代码为:
import math,time
t=time.time()
#sieve method for getting list of primes.
def getprimes(n):
if n==2: return [2]
elif n<2: return []
s=range(3,n+1,2)
mroot = n ** 0.5
half=(n+1)/2-1
i=0;m=3
while m <= mroot:
if s[i]:
j=(m*m-3)/2;s[j]=0
while j<half:
s[j]=0;j+=m
i=i+1;m=2*i+3
return [2]+[x for x in s if x]
# filter bad primes
goodNums=set(['1','3','7','9'])
good_filter=lambda x: not set(str(x)).difference(goodNums)
primes=filter(good_filter,getprimes(1000000))
def rotate(n_str):
return n_str[-1]+n_str[:-1]
def isCircullar(n_str):
global primes
for i in range(len(n_str)-1):
n_str=rotate(n_str)
if not int(n_str) in primes:
return 0
return 1
circullarCounter=lambda x,y:x+isCircullar(str(y))
#explicitly include 2 and 5 to circullar primes (excluded at filtering procedure)
print reduce(circullarCounter,primes,2)
print time.time()-t
运行结果为
55
0.297000169754
呃呃。。才0.2秒,我了个去。。比我快10倍啊。。都不知道是多少个数量级了。艹 了。
看了别人的改了的:
#coding=utf-8
import math,time
t=time.time()
def isprime(n):#判断是不是素数
if n==2:
return True
else:
for x in xrange(3,int(math.sqrt(n))+1,2):
if not n%x:
return False
return True
def geprime(n):#其实是获取所有奇数
relist=[2]
sourceclist=[-1]*n
for num in xrange(3,n,2):
if sourceclist[num]==1:
continue
for tempnum in xrange(num,n,2*num):
sourceclist[tempnum]=1
relist.append(num)
return relist
def getloop(n):
reset=set()
n_str=str(n)
temp_str=n_str
for i in range(len(n_str)):
temp_str=temp_str[-1]+temp_str[:-1]
reset.add(temp_str)
return { int(numstr) for numstr in reset}
goodnumlist=['1','3','7','9']
onesteplist=geprime(1000000)
#print onesteplist
b=lambda x: not set(str(x)).difference(goodnumlist)
goodprimelist=filter(b,set(onesteplist))
#print goodprimelist
#comparedict=dict.fromkeys(goodprimelist,0)
primeset=set()
print time.time()-t
for key in goodprimelist:
if not key in primeset:
tempset=getloop(key)
tempsuccess=True
for tempnum in tempset:
if tempsuccess==True and tempnum not in goodprimelist:
tempsuccess=False
break
#comparedict[tempnum]=1
if tempsuccess==True:
primeset.update(tempset)
print len(filter(lambda x:isprime(x),primeset))+2#里面不包含2,5,所以计数的时候要+2
print time.time()-t
运行结果为:
0.3140001297
55
0.360000133514
呃呃。。。慢了快1/2了。艹 了。。。
等下再研究下为什么会这个样子呃呃。。。
终于把速度提升上去了。
耗时最多的是getprimes()那里。
有两点体会:
1.有时候顺序很重要,像这里的我把isprime()这种比较耗时,移到最后。总时间就会大大减少
2.sourcelist牛人的数据结构真的很重要。。用了他的速度就上去了。
代码为:
__author__ = 'Administrator'
import math,time
t=time.time()
#sieve method for getting list of primes.
def getprimes(n):
if n==2: return [2]
elif n<2: return []
s=range(3,n+1,2)
mroot = n ** 0.5
half=(n+1)/2-1
i=0;m=3
while m <= mroot:
if s[i]:
j=(m*m-3)/2;s[j]=0
while j<half:
s[j]=0;j+=m
i=i+1;m=2*i+3
return [2]+[x for x in s if x]
# filter bad primes
goodNums=set(['1','3','7','9'])
good_filter=lambda x: not set(str(x)).difference(goodNums)
#print sorted(list(getprimes(1000000)))
primes=filter(good_filter,getprimes(1000000))
print time.time()-t
def rotate(n_str):
return n_str[-1]+n_str[:-1]
def isCircullar(n_str):
global primes
for i in range(len(n_str)-1):
n_str=rotate(n_str)
if not int(n_str) in primes:
return 0
return 1
circullarCounter=lambda x,y:x+isCircullar(str(y))
#explicitly include 2 and 5 to circullar primes (excluded at filtering procedure)
print reduce(circullarCounter,primes,2)
print time.time()-t
结果:
55
0.302999973297