Вопрос вот какой.
Выяснил я тут намедни, что в pari/gp есть средства по созданию словарей, помещении и извлечению оттуда значений.
Это удобно если есть функция, которая может долго рекурсивно вычисляться, много раз повторно. Тогда мы по мере вычислений, кладем вычисленные значения в словарь и повторно вычислять не надо - берем из словаря.
Мемоизация, короче.
Но есть проблемка.
Функция, которая делает вычисления - рекурсивная. Соответственно, словарь должен быть более глобальным чем внутренность функции. Я читал доки по pari/gp и не понял как сделать одну (рекурсивную) функцию внутри другой, чтобы
во внешней функции объявлялась переменная (словарь), затем вызывалась внутренняя (рекурсивная) функция, которая бы могла пользоваться словарём, а по окончании вычислений словарь бы удалялся.
Собсно, вот код. Функция
p(n,k) -- рекурсивная функция которая вычисляет количество разбиений числа
n на не более чем
k частей. Переменная
M - более глобальная (внешняя) по отношению к функции
p().
Код:
p(n,k)={
my(res=0);
if(n==0 && k==0, /* проверяем первое условие*/
return(1)); /* возвращаем результат если выполняется */
if(k<1, /* проверяем второе условие */
return(0)); /* возвращаем результат если выполняется */
if(mapisdefined(M,[n,k],&res), /* проверяем вычислялось ли уже значение */
return(res)); /* возвращаем результат если вычислялось */
if(k>=n, /* проверяем третье условие */
res=numbpart(n); /* если выполняется то вычисляем нерекурсивным методом */
mapput(M,[n,k],res); /* кладем результат в словарь */
return(res)); /* возвращаем результат */
res=p(n,k-1)+p(n-k,k); /* никакие условия не сработали, вычисляем через рекурсию */
mapput(M,[n,k],res); /*кладем результат в словарь */
return(res)} /* возвращаем результат */
Вызывать надо так:
1. создаём глобальный пустой словарь
? M=Map();2. запускаем вычисления
? n=p(100,30);print(n)
1649557003. удаляем словарь
? kill(M)Надо сделать чтобы все три пункта делались внутри какой-то (внешней по отношению к
p()) функции. Как это можно и можно ли устроить?