项目欧拉92

时间:2015-08-04 14:09:04

标签: python math

我解决problem 92的代码是正确的,但速度太慢,因此我尝试通过仅针对该数字的每种可能排列考虑一个数字来修改它,从而有效地将问题的大小从原来的10减少到11439百万。这是我的代码

import time
from Euler import multCoeff

start = time.time()

def newNum(n):
    return sum([int(dig)**2 for dig in str(n)])

def chain(n, l):
    if n in l:
        return n, l
    else:
        l.append(n)
        return chain(newNum(n), l)

nums = []

for i in range(1,10000000):
    if all(str(i)[j] <= str(i)[j+1] for j in range(len(str(i))-1)):
        nums.append(i)

count = 0   

for i in nums:
    if 89 in chain(i,[])[1]: 
        perms = multCoeff(i)
        count += perms

end = time.time() - start            

print count, end

multCoeff是我创建的方法,基本上等同于len(set(permutations([int(j) for j in str(i)]))) 工作得很好。无论如何,问题是我得到的结果不正确,看起来我忽略了一些情况,但我真的看不出哪些。如果有人能指出我正确的方向,我真的很感激。感谢。

1 个答案:

答案 0 :(得分:2)

我们错过了multCoeff的代码,所以我猜这里。

你试图通过排除没有按升序排列的数字然后重新计算它们的排列来从1到999,999,999进行过滤。

您的问题是0

根据您的过滤器2, 20, 200, 2000, 20000, 200000, 2000000全部由2表示,但您可能不会添加这么多排列。

关于您的代码的一般观察:

  • item in listO(n) time complexity;尽量避免为大型列表执行此操作。
  • 您正在丢弃许多计算的结果;导致891的链中的任何数字都将始终具有最终结果。
  • 每个函数调用都有时间成本;尽量使循环调用中的函数数量保持较低。
  • str投射到int有点贵;尽量保持演员阵容的数量最少。