42的除数是:1,2,3,6,7,14,21,42。这些除数的平方是:1,4,9,36,49,196,441,1764。平方的总和除数是2500,即50 * 50,一个正方形!
给定两个整数m,n(1 <= m <= n)我们想要找到m和n之间的所有整数,其平方除数之和本身就是一个平方。 42就是这样的数字。
结果将是一个数组数组,每个子数组有两个元素,首先是平方除数为平方的数字,然后是平方除数的总和。
示例:
list_squared(1,250) - &gt; [[1,1],[42,2500],[246,84100]]
list_squared(42,250) - &gt; [[42,2500],[246,84100]]
以上是该问题的讲师。
我在Coderwars练习时遇到问题。我的代码已通过所有测试,但有一个错误“超时”,这意味着我的代码不是很好。我可以改进它。以下是我的解决方案。
from math import sqrt
def get_div(x):
s = []
for i in range(1,x):
if x%i == 0:
# print i, x/i
s.append(i)
s.append(x/i)
return set(s)
def list_squared(m, n):
p = []
for i in range(m,n):
if i == 1:
p.append([1,1])
continue
s = sum(a**2 for a in get_div(i))
if float(sqrt(s)).is_integer():
p.append([i,s])
return p
答案 0 :(得分:1)
我建议两件事:
1)为什么不将它改为get_div_squared_sum而只返回总和?而不是get_div并返回一个数组?你只是使用那个数组总和,所以如果你只计算函数中的和,那么你将失去一个完整的for循环。
2)已经提到过,但你只需要去sqrt(x)就可以得到所有可能的除数。
答案 1 :(得分:1)
根据此问题的答案Algorithm to calculate the number of divisors of a given number以及@ devin-white的评论,您可能需要尝试以下解决方案。
def divisors_squared_sum(x):
limit = x
squared_sum = 0
if x==1:
return 1
i = 1
while True:
if x % i == 0:
limit = x / i
if limit != i:
squared_sum += limit**2
squared_sum += i**2
i += 1
if i >= limit:
return squared_sum
def list_squared2(start, end):
res = []
for i in xrange(start, end):
squared_sum = divisors_squared_sum(i)
sqrt_sum = np.sqrt(squared_sum)
if int(sqrt_sum) == sqrt_sum:
res.append([i, squared_sum])
return res
我得到以下结果:
In [24]: %timeit list_squared(1, 250)
100 loops, best of 3: 3.6 ms per loop
In [25]: %timeit list_squared2(1, 250)
100 loops, best of 3: 1.96 ms per loop