我试图编写一个python脚本,它查找所有整数(n),其中n的位数和的某个幂等于n。例如,n=81符合条件,因为8+1=9,而9的某个幂(即2=81)。
我选择的范围是任意的。我的剧本很好用,但很慢。理想情况下,我想在大约6000ms内找到前30个这样的整数。
我的第一个解决方案:

def powerOfSum1():
    listOfN = []
    arange = [a for a in range(11, 1000000)] #range of potential Ns
    prange = [a for a in range(2, 6)] # a range for the powers to calculate
    for num in arange:
        sumOfDigits = sum(map(int, str(num)))
        powersOfSum = [sumOfDigits**p for p in prange]
        if num in powersOfSum:
            listOfN.append(num)
    return listOfN

在我的第二个解决方案中,我尝试存储每个相扑数字的所有能力,但这并没有大大提高性能。
def powerOfSum2():
    listOfN = []
    powers= {}
    for num in range(11, 1000000):
        sumOfDigits = sum(map(int, str(num)))
        summ = str(sumOfDigits)
        if summ in powers:
            if num in powers[summ]:
                listOfN.append(num)
        else:
            powersOfSum = [sumOfDigits**p for p in range(2,6)]
            powers[summ] = powersOfSum
            if num in powers[summ]:
                listOfN.append(num)
    return listOfN

我还没有研究过数据结构和算法,所以我很欣赏任何关于提高脚本效率的建议。

最佳答案

更新:我发现这是一个项目Euler问题(119),我发现基本上相同的解决方案已经记录在案:http://www.mathblog.dk/project-euler-119-sum-of-digits-raised-power/
我不确定是否过于简化了,但仅仅是迭代一系列数字的幂似乎很快。你不能保证订单,所以计算出超过你需要的数量,然后排序并进入前30名。我不能证明我已经得到了所有的,但我已经测试了base500和exp50,它返回了同样的前30名。应该注意的是,只有OP测试的指数高达5,这大大限制了结果的数量:

def powerOfSum():
    listOfN = []
    for base in range(2, 100):
        num = base
        for _ in range(2, 10):
            num *= base
            if sum(map(int, str(num))) == base:
                listOfN.append(num)
    return sorted(listOfN)[:30]
powerOfSum()

产量
[81,
 512,
 2401,
 4913,
 5832,
 17576,
 19683,
 234256,
 390625,
 614656,
 1679616,
 17210368,
 34012224,
 52521875,
 60466176,
 205962976,
 612220032,
 8303765625,
 10460353203,
 24794911296,
 27512614111,
 52523350144,
 68719476736,
 271818611107,
 1174711139837,
 2207984167552,
 6722988818432,
 20047612231936,
 72301961339136,
 248155780267521]

在上面运行(包括排序),我得到:
100 loops, best of 3: 1.37 ms per loop

08-24 16:09