Python:简化棕色数字的代码
我很好奇你们中是否有人能想出一个更精简的版本来计算布朗数。到目前为止,此代码可以执行Python:简化棕色数字的代码,python,python-3.x,math,Python,Python 3.x,Math,我很好奇你们中是否有人能想出一个更精简的版本来计算布朗数。到目前为止,此代码可以执行~650移动到爬网之前。布朗数的计算公式为n!+1=m**(2)其中m是一个整数 brownNum = 8 import math def squareNum(n): x = n // 2 seen = set([x]) while x * x != n: x = (x + (n // x)) // 2
~650代码>移动到爬网之前。布朗数的计算公式为n!+1=m**(2)
其中m
是一个整数
brownNum = 8
import math
def squareNum(n):
x = n // 2
seen = set([x])
while x * x != n:
x = (x + (n // x)) // 2
if x in seen: return False
seen.add(x)
return True
while True:
for i in range(math.factorial(brownNum)+1,math.factorial(brownNum)+2):
if squareNum(i) is True:
print("pass")
print(brownNum)
print(math.factorial(brownNum)+1)
break
else:
print(brownNum)
print(math.factorial(brownNum)+1)
brownNum = brownNum + 1
continue
break
print(input(" "))
我要做的一个优化是围绕math.factorial实现一个“wrapper”函数,该函数缓存factorial的先前值,这样随着brownNum的增加,factorial就没有那么多工作要做了。这在计算机科学中被称为“记忆”
编辑:找到另一个具有类似意图的SO答案:您可能希望:
- 预先计算你的平方数,而不是动态测试它们
- 为每个循环迭代预先计算阶乘
num\u fac=math.factorial(brownNum)
,而不是多次调用
- 实现您自己的、记忆化的阶乘
这应该可以让您运行到机器的硬限制您还应该更接近于根来初始化平方根
e = int(math.log(n,4))
x = n//2**e
因为4**e对不起,我不理解你代码背后的逻辑
我不明白为什么每次通过while True
循环计算math.factorial(brownNum)
4次,每次都使用相同的brownNum
值。在for
循环中:
for i in range(math.factorial(brownNum)+1,math.factorial(brownNum)+2):
i
将只接受math.factorial(brownNum)+1的值
无论如何,这里是我的Python3代码,用于对的暴力搜索。它很快找到仅有的3对已知数字,然后在这个2GHz 32位机器上,在大约1.8秒内测试1000以下的所有其他数字。在这一点之后,你可以看到它变慢了(在20秒左右达到2000),但它会愉快地前进,直到阶乘变得太大以至于你的机器无法承受
我将进度信息打印到stderr,以便将其与Brown_编号对输出分离。另外,当您不打印换行符时,stderr不需要刷新,这与stdout不同(至少在Linux上不需要)
导入系统
#使用牛顿法计算'm'的整数平方根。
#返回r:r**2>1
r+=d
如果-1
#搜索布朗的号码
fac=i=1
尽管如此:
如果i%100==0:
打印('\r',i,file=sys.stderr,end='')
fac*=i
n=fac+1
r=int_sqrt(n)
如果r*r==n:
打印('\n查找',i,r)
i+=1
Wrapper function?@Z.B是的,如果您有一个正在调用的函数(如math.factorial),“Wrapper”函数是您编写的一个函数,它本身最终会调用math.factorial,但您应该实现Wrapper函数,在调用math.factorial之前将条目获取/放入缓存中。这是我粘贴的链接中的一个例子,感谢Senthil Kumaran:import math cache={}def myfact(x):return cache.setdefault(x,math.factorial(x))@PM 2如果公式对正确的等式执行,那么这是帖子中的一个错误。
import sys
# Calculate the integer square root of `m` using Newton's method.
# Returns r: r**2 <= m < (r+1)**2
def int_sqrt(m):
if m <= 0:
return 0
n = m << 2
r = n >> (n.bit_length() // 2)
while True:
d = (n // r - r) >> 1
r += d
if -1 <= d <= 1:
break
return r >> 1
# Search for Browns numbers
fac = i = 1
while True:
if i % 100 == 0:
print('\r', i, file=sys.stderr, end='')
fac *= i
n = fac + 1
r = int_sqrt(n)
if r*r == n:
print('\nFound', i, r)
i += 1