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