Это может быть достигнуто еще быстрее, если искать пару (x, y)
, которая удовлетворяет уравнению для данного квадрата в вашем целевом диапазоне.Фактически это уменьшает проблему со O(n^2)
до O(nlogn)
сложности времени.
def split_root(n):
div = 10
while div < n:
x, y = divmod(n, div)
div *= 10
if not y or y < div // 100: continue
if (x + y) ** 2 == n: yield x, y
Затем просто выполните итерации по возможным квадратам:
def squares(n):
for i in range(n):
for sr in split_root(i ** 2):
yield "({}+{})^2 = {}".format(*sr, sum(sr)**2)
Пример использования:
print("\n".join(squares(100000)))
Вывод:
(8+1)^2 = 81
(20+25)^2 = 2025
(30+25)^2 = 3025
(88+209)^2 = 88209
(494+209)^2 = 494209
(494+1729)^2 = 4941729
(744+1984)^2 = 7441984
(2450+2500)^2 = 24502500
(2550+2500)^2 = 25502500
(5288+1984)^2 = 52881984
(6048+1729)^2 = 60481729
(3008+14336)^2 = 300814336
(4938+17284)^2 = 493817284
(60494+17284)^2 = 6049417284
(68320+14336)^2 = 6832014336
Для сравнения, ваше оригинальное решение -
def op_solver(n):
solutions = []
for i in range(1,n+1):
for j in range(1,n+1):
if str((i+j)**2)==str(i)+str(j):
solutions.append("("+str(i)+"+"+str(j)+")^2 = "+str((i+j)**2))
return solutions
>>> timeit("op_solver(1000)", setup="from __main__ import op_solver", number=5) / 5
0.8715057126013562
Мое решение -
>>> timeit("list(squares(2000))", setup="from __main__ import squares", number=100) / 100
0.006898956680088304
Примерно 125-кратное ускорение дляпример использования, и он будет работать асимптотически быстрее по мере роста n
.
Это также дает преимущество, заключающееся в том, что он быстрее и проще, чем решение с numpy, и, конечно, не требует numpy.Если вам нужна более быстрая версия, я уверен, что вы даже можете векторизовать мой код, чтобы получить лучшее из обоих миров.