我试图编写一个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名。我不能证明我已经得到了所有的,但我已经测试了base
500和exp
50,它返回了同样的前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