Xue Chuancong Xue Chuancong - 8 months ago 52
Python Question

How to improve this solution?

Divisors of 42 are : 1, 2, 3, 6, 7, 14, 21, 42. These divisors squared are: 1, 4, 9, 36, 49, 196, 441, 1764. The sum of the squared divisors is 2500 which is 50 * 50, a square!

Given two integers m, n (1 <= m <= n) we want to find all integers between m and n whose sum of squared divisors is itself a square. 42 is such a number.

The result will be an array of arrays, each subarray having two elements, first the number whose squared divisors is a square and then the sum of the squared divisors.


list_squared(1, 250) --> [[1, 1], [42, 2500], [246, 84100]]

list_squared(42, 250) --> [[42, 2500], [246, 84100]]

above is the instructor of the question.

I have a problem when do the practice of Coderwars. my code have passed all tests, but have a error "timeout", it means my code is not very good.how can I improve it. Below is my solution.

from math import sqrt
def get_div(x):
s = []
for i in range(1,x):
if x%i == 0:
# print i, x/i
return set(s)

def list_squared(m, n):
p = []
for i in range(m,n):
if i == 1:
s = sum(a**2 for a in get_div(i))
if float(sqrt(s)).is_integer():
return p


Two things I would suggest:

1) Instead of get_div and returning an array, why not change it to get_div_squared_sum and just return the sum? You're only using that array to sum anyway so if you just calculate the sum in the function then you lose an entire for loop.

2) It's been mentioned already but you only need to go to sqrt(x) in order to get every possible divisor.