аватар question@mail.ru · 01.01.1970 03:00

RecursionError: maximum recursion depth exceeded - как преодолеть?

Есть задача в ; есть ее решение, где по изяществу Python ""победил"" C#, но вот у же на х=512 вылетает RecursionError: что посоветуете, отцы? Как преодолеть, если хочется посчитать для х=1024 скажем?

n
import functools nfrom math import sqrtn@functools.lru_cache()ndef f(x):n    if x <=1: retu 0n    retu 1 + min([ f(m + x // m - 2)  for m in range(1,int(sqrt(x))+1) if x%m ==0])n
n

добавлю после первого ответа:

n

Кто предложит как изменить алгоритм?

n

Кстати. Добавил количество рекурсии до 5000. Получается странная фигня. для 1024 считает, делая 3600 итераций, а для 2048 - ""выбивает"" интерпретатор на 1000+ рекурсии. Вообще не пойму - в чем проблема....

аватар answer@mail.ru · 01.01.1970 03:00

Я размещу код, предложенный @Harry на С++, переведенный мною на Python для сохранения ""тематики"" языка на странице. Решение принадлежит ему. В любом случае - как всегда решает на язык, а мозг Ж-)

n
import numpy as npnfrom math import sqrtnMAXSIZE = 1000000000nm = np.zeros(MAXSIZE+1, dtype=np.int16)ndef f(x, level=0, curmin = MAXSIZE) -> int: n    if level > curmin: retu -1 # Отсечение - нет смысла лезть вглубьn                                 # при наличии более короткого решенияn    if x == 1: retu 0n    if m[x]: retu m[x]      # Сохраненное значениеn    res = MAXSIZE;n    for i in range(int(sqrt(x))+1, 0, -1):n        if x%i: continue;n        k = f(i+x//i-2, level+1, res);n        if k < 0: continue;n        if k < res:  res = kn        m[x] = res+1n    retu m[x]nn = int(input(""дай целое!""))nprint( n, "": "", f(n))n
n

вывод подробностей решения:

n
cur = m[n]nwhile n>1:n    for i in range(1,int(sqrt(n))+1):n        if n%i: continuen        if m[i+n//i-2] == cur-1:n            n = i+n//i-2n            cur -=1n            print(i, end=' ')n            breaknprint("""")n
n

Разница между этим кодом и кодом приведенным в вопросе - такова. Он работает для числа 1 000 000 000, в то время как исходный код ""вырубал"" интерпретатор уже на 2048. Ручное кэширование оказалось надежнее встроенного в пайтон, и - важнее всего -отсечение неправильных вариантов заметно сократило время.

Последние

Похожие