如何改进这个解决方案?

时间:2016-10-26 16:05:56

标签: python

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

2 个答案:

答案 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