[英](the first 10-digit prime in e).com python google challenge 2004
I just come up to one of challenges that claimed to be used by google 2004我刚刚遇到了声称被 google 2004 使用的挑战之一
(the first 10-digit prime in e).com
independent from that, I wanted to take the challenge and solve it with python独立于此,我想接受挑战并用python解决它
>>> '%0.52f' % math.exp(1)
'2.71828182845904509079**5598298427**6488423347473144531250'
>>> '%0.52f' % numpy.exp(1)
'2.71828182845904509079**5598298427**6488423347473144531250'
my program returned 5598298427
which is a prime number我的程序返回
5598298427
这是一个素数
after looking on the internet the right answer was 7427466391
在互联网上查找后正确答案是
7427466391
but the exp number in python doesn't include that digits as you can see above但是如上所示,python 中的 exp 数字不包括该数字
import numpy
import math
def prime(a):
if a == 2: return True
if a % 2 == 0: return False
if a < 2: return False
i = 2
n = math.sqrt(a) + 1
while(i < n):
if a % i == 0:
return False
i += 1
return True
def prime_e():
e = '%0.51f' % math.exp(1)
e = e.replace("2.","")
for i in range(len(e)):
x = int(e[i:10+i])
if prime(x):
return [i, x]
print prime_e()
so am I doing something wrong ?那我做错了吗?
EDIT: using gmpy2编辑:使用 gmpy2
def exp():
with gmpy2.local_context(gmpy2.context(), precision=100) as ctx:
ctx.precision += 1000
return gmpy2.exp(1)
returns 7427466391
after 99 iterations 99 次迭代后返回
7427466391
Actual e ( Euler constant ) value is实际e (欧拉常数)值为
http://www.gutenberg.org/files/127/127.txt http://www.gutenberg.org/files/127/127.txt
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642 7427466391 932003059921817413596629043572900334295260595630...
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642 7427466391 932003059921817413596629043572900334295260595630...
and so the right answer for the challenge is 7427466391
.所以挑战的正确答案是
7427466391
。 You can't compute e with requiered precision by math.exp(1)
您无法通过
math.exp(1)
以所需的精度计算 e
Here is a way to do it:这是一种方法:
Generate 1st 1000 digits of e using continued fractions method with answer by @quantum in Code to Generate e one Digit at a Time , which is from answer by @wnoise in Generating digits of square root of 2 , which is an "adaptation of Haskell code ... that has been floating around":使用连分数法生成 e 的第一个 1000 位,@quantum 在Code to Generate e one Digit at a Time中回答,这是来自 @wnoise 在生成 2 的平方根的数字中的回答,这是“对 Haskell 代码的改编......一直在漂浮”:
def z(contfrac, a=1, b=0, c=0, d=1):
for x in contfrac:
while a > 0 and b > 0 and c > 0 and d > 0:
t = a // c
t2 = b // d
if not t == t2:
break
yield t
a = (10 * (a - c*t))
b = (10 * (b - d*t))
# continue with same fraction, don't pull new x
a, b = x*a+b, a
c, d = x*c+d, c
for digit in rdigits(a, c):
yield digit
def rdigits(p, q):
while p > 0:
if p > q:
d = p // q
p = p - q * d
else:
d = (10 * p) // q
p = 10 * p - q * d
yield d
def e_cf_expansion():
yield 1
k = 0
while True:
yield k
k += 2
yield 1
yield 1
def e_dec():
return z(e_cf_expansion())
gen = e_dec()
e = [str(gen.next()) for i in xrange(1000)]
e.insert(1, '.')
Function to test primality of an integer selected for efficiency from Rosetta Code Primality_by_trial_division#Python :用于测试从Rosetta Code Primality_by_trial_division#Python中选择的整数的素数的函数:
def isprime(a):
if a < 2: return False
if a == 2 or a == 3: return True # manually test 2 and 3
if a % 2 == 0 or a % 3 == 0: return False # exclude multiples of 2 and 3
maxDivisor = a**0.5
d, i = 5, 2
while d <= maxDivisor:
if a % d == 0: return False
d += i
i = 6 - i # this modifies 2 into 4 and viceversa
return True
Find the first 10 digit prime in e (my contribution):找出 e 中的前 10 位素数(我的贡献):
for i in range(len(e[2:])-10):
x = int(reduce(operator.add,e[2:][i:i+10]))
if isprime(x):
print x
print i
break
This prints:这打印:
7427466391
98
Meaning that the first 10 digit prime in e occurs in the 98th postion after the decimal point in agreement with http://explorepdx.com/firsten.html under 'The location of the answer'.这意味着 e 中的前 10 位素数出现在小数点后的第 98 位,这与“答案的位置”下的http://explorepdx.com/firsten.html一致。
A simpler way to generate digits of e is with Euler's series expansion which can be done as follows with code adapted from Euler's Number with 100 Digit Precision (Python) that uses Python's Decimal class for adequate precision:生成 e 的数字的一种更简单的方法是使用欧拉级数展开,它可以使用从具有 100 位精度的欧拉数 (Python)改编的代码来完成,该代码使用 Python 的 Decimal 类以获得足够的精度:
import operator
import decimal as dc
def edigits(p):
dc.getcontext().prec = p
factorial = 1
euler = 2
for x in range(2, 150):
factorial *= x
euler += dc.Decimal(str(1.0))/dc.Decimal(str(factorial))
return euler
estring = edigits(150).to_eng_string()[2:]
for i in range(len(estring)-10):
x = int(reduce(operator.add,estring[i:i+10]))
if isprime(x):
print x
print i
break
This prints:这打印:
7427466391
98
As pointed out by @MarkDickinson an even easier method is to use the decimal module directly to generate e with the necessary precision.正如@MarkDickinson 所指出的,一种更简单的方法是直接使用 decimal 模块以必要的精度生成 e 。 For example:
例如:
import operator
import decimal
decimal.getcontext().prec = 150
e_from_decimal = decimal.Decimal(1).exp().to_eng_string()[2:]
for i in range(len(e_from_decimal)-10):
x = int(reduce(operator.add,e_from_decimal[i:i+10]))
if isprime(x):
print x
print i
break
This prints:这打印:
7427466391
98
The problem is that your 'e' is wrong after the 15th decimal (09079 and onwards) for reasons that others have explained here.问题是您的“e”在小数点后 15 位(09079 及以后)之后是错误的,原因其他人已在此处解释。 However, python itself has all the tools onboard to provide 'e' with virtually unlimited precision.
但是,python 本身具有所有板载工具,可以为“e”提供几乎无限的精度。 I haven't come across this solution yet, so I decided to post it here.
我还没有遇到这个解决方案,所以我决定在这里发布。 The magic is in the 'long' int, which can be as long as the memory of your machine permits.
神奇之处在于'long' int,只要您的机器内存允许,它就可以。 Since a float is nothing more than an int divided by some power of 10, we can easily calculate (and store) e_as_int=e*10**d, where d is the number of required decimals.
由于浮点数只不过是整数除以 10 的某个幂,因此我们可以轻松计算(并存储)e_as_int=e*10**d,其中 d 是所需的小数位数。 The simple code below generates e from the series for the natural logarithm:
下面的简单代码从自然对数系列生成 e:
import itertools
count = itertools.count
def ape(digits):
# e = sum(1/k! for k in count())
# calculate some extra digits to compensate for loss of precision:
r = 3
m = 10**(digits+r)
e = 2*m
f = 1 #initial value for k!
for k in count(2):
f *= k
if f>m: break
# remember, we're doing int division, so m/f = 0 for f>m
e += (m/f)
return e/10**r #truncate to required precision
'ape' stands for 'approximation of e' and reflects the simplicity of it quite well:-) This algo finds 10000 digits of e in about a second on my machine. 'ape' 代表 'approximation of e' 并很好地反映了它的简单性:-) 这个算法在我的机器上大约一秒钟内找到了 10000 位 e。
You know I appreciate everyone making theres super efficient and complicated, but if you want the poor mans solution to the problem (ie. lamen terms) here V你知道我很欣赏每个人都让那里变得超级高效和复杂,但是如果你想要穷人解决这个问题(即蹩脚条款)这里 V
def is_Prime(num):
for i in range(2, num):
if num % i == 0:
return False
return True
e = '2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174'
value = 4
left = 1
while is_Prime(value) == False:
left += 1
value = e[left] + e[left + 1] + e[left + 2] + e[left + 3] + e[left + 4] + e[left + 5] + e[left + 6] + e[left + 7] + e[left + 8] + e[left + 9]
value = int(value)
print(value)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.