什么限制会导致此脚本卡住?

时间:2019-05-14 22:32:28

标签: python

我正在使用python进行数学难题,您可以找到长度为k位的数字序列,其中每个数字的乘积等于数字的总和,即k = 3 1 * 2 * 3 = 1 + 2 + 3

我是python和程序设计的新手,我很好奇为什么会有“下降”的地方,它可以很快地评估到某个点,然后程序陷入困境。

psnumbers = []

#this gives me a number to start a for loop later in the script
def ones(n):
    string = '1'*n
    return int(string)

#multiplies and adds the digits together and compares the values
def check(n):
    global psnumbers
    add = 0
    mult = 1
    for i in range(len(n)):
        add += int(n[i])
        mult*= int(n[i])
    if add == mult and n[0] != 0:
        print(n)
        psnumbers.append(n)
        return True
    else:
        return False

#starts checking numbers, starting with the value from ones()      
def loop(n):
    for x in range(2,n+1):
        for i in range(ones(x),ones(x)*2):
            if check(str(i)) == True:
                break
            else:
                continue

#loop(23) works for me fine, but loop(n) where n>=24 doesn't finish processing      
loop(23)

loop(n)的所有值(其中n <= 23)也完全按照我希望的方式工作,并且脚本在不到半秒钟的时间内完成。但是,对于n值为24或更大的值,脚本生成的值将达到针对loop(23)输出的值,并陷入阻塞处理状态。什么问题会导致这种情况?

2 个答案:

答案 0 :(得分:2)

您确定在n = 24处有解决方案吗?我认为您的代码按预期工作,将花费很长时间才能找到正确的答案。 我更改了循环,以便仅在n = 24处寻找解决方案,并输出正在尝试的数字...这将允许您在命令行上运行它,并输出正在尝试的数字,您可以知道为什么要花这么长时间。

def loop(n):
    x = n
    for i in range(ones(x),ones(x)*2):
        print('\r' + str(i), end='')
        if check(str(i)) == True:
            break
        else:
                continue
    print('done')

这个数字高得多。

n=23 >> 11111111111111111111228

n=24 >> 111111111111111112163473才达到jupy笔记本的限制。

我不确定您是否有时间解决计算机问题,因为您每秒可以检查1000个数字,这将需要10^24 * 10^-4 = 10^20 seconds ...或1.15740741 × 1015 days。您可能会做一些棘手的逻辑,以避免两次检查相同的数字(算法等于112 == 121)。

您的问题“为什么需要更长的时间”的答案是,答案与n = 24的起点相比比n = 23的起点要远得多。

答案 1 :(得分:1)

找到任意给定字符串长度的单个解决方案后,您的代码退出。碰巧的是,对于任何n到23的值都有一个简单的解决方案。

但是,当我们到达n = 24时,所有前导1的开销最终都超过了小数字的各种数值属性,因此没有这样的解决方案。

我更改了算法中的工具,找到了 all 这样的数字,并在每个循环前后添加了一个简单的time()调用。

def loop(n):
    for x in range(2,n+1):
        start = time()
        for i in range(ones(x),ones(x)*2):
            check(str(i))
        print(x, time() - start)

n的前几个值的计时是

n     time (sec)
2 0.00010895729064941406
3 0.0007987022399902344
4 0.008989572525024414
5 0.08109426498413086
6 0.6398007869720459
7 6.47220778465271
8 70.14981818199158

如果编写代码以仅处理非递减序列(数字按数字顺序排序),并进行检查以确保乘积在总和范围之内,则可以大大提高速度。 / p>