Python, 52 байта
f=lambda l,n:n*l and f(f(l[:-1],1)+[sum(l)],n-1)or l
Рекурсивная функция, которая повторяется как по списку, так l
и по количеству итераций n
. Давайте разберемся с этим.
Во-первых, давайте рассмотрим рекурсивную функцию, g
которая повторяла частичную сумму только один раз.
g=lambda l:l and g(l[:-1])+[sum(l)]
Для пустого списка l
это возвращает l
себя, пустой список. В противном случае последняя запись частичных сумм l
является общей суммой l
, которая добавляется к рекурсивному результату для всех, кроме последнего элементаl
.
Теперь давайте посмотрим на функцию, f
которая применяется g
для n
итераций.
f=lambda l,n:n and f(g(l),n-1)or l
Когда n
есть 0
, это возвращает список l
без изменений, и в противном случае, применяется g
один раз, затем вызываетf
рекурсивно с оставшимся меньшим количеством итераций.
Теперь давайте снова посмотрим на реальный код, который объединяет две рекурсии в одну функцию. Идея состоит в том, чтобы рассматривать g(l)
как особый случай f(l,1)
.
f=lambda l,n:n*l and f(f(l[:-1],1)+[sum(l)],n-1)or l
Мы взяли f(g(l),n-1)
из предыдущего определения, расширяется g(l)
в g(l[:-1])+[sum(l)]
, а затем заменить g(_)
с f(_,1)
на приурочены рекурсивные вызовы вf
.
Для базового случая мы хотим вернуться l
всякий раз, когда n==0
или l==[]
. Мы объединяем их, отмечая, что любой из них n*l
является пустым списком, то есть ложью. Итак, мы возвращаемся, когда n*l
не пусто, и возвращаемl
противном случае.
Даже если есть два рекурсивных вызова f
, это не вызывает экспоненциального увеличения рекурсивного определения чисел Фибоначчи, но остается квадратичным.