Збіжні суми фрактальної послідовності


16

Фон

Фрактальна послідовність являє собою ціле число послідовностей , де можна видалити перше входження будь-якого цілого і в кінцевому підсумку з тієї ж самої послідовністю , як і раніше.

Дуже проста така послідовність називається парафразами Кімберлінга . Ви починаєте з натуральних натуральних чисел:

1, 2, 3, 4, 5, 6, 7, 8, 9, ...

Тоді ви наріжете кілька заготовок:

1, _, 2, _, 3, _, 4, _, 5, _, 6, _, 7, _, 8, _, 9, ...

А потім ви кілька разів заповнюєте заготовки самою послідовністю (включаючи пробіли):

1, 1, 2, _, 3, 2, 4, _, 5, 3, 6, _, 7, 4, 8, _, 9, ...
1, 1, 2, 1, 3, 2, 4, _, 5, 3, 6, 2, 7, 4, 8, _, 9, ...
1, 1, 2, 1, 3, 2, 4, 1, 5, 3, 6, 2, 7, 4, 8, _, 9, ...
1, 1, 2, 1, 3, 2, 4, 1, 5, 3, 6, 2, 7, 4, 8, 1, 9, ...

Ось наша фрактальна послідовність! Тепер візьмемо часткові суми:

1, 2, 4, 5, 8, 10, 14, 15, 20, 23, 29, 31, 38, 42, 50, 51, 60, ...

Але що робити, якщо ми повторимо цей процес? "Фракталізація" нової послідовності (тобто часткові суми, отримані за кроками вище):

1, _, 2, _, 4, _, 5, _, 8, _, 10, _, 14, _, 15, _, 20, _, 23, ...
1, 1, 2, _, 4, 2, 5, _, 8, 4, 10, _, 14, 5, 15, _, 20, 8, 23, ...
1, 1, 2, 1, 4, 2, 5, _, 8, 4, 10, 2, 14, 5, 15, _, 20, 8, 23, ...
1, 1, 2, 1, 4, 2, 5, 1, 8, 4, 10, 2, 14, 5, 15, _, 20, 8, 23, ...
1, 1, 2, 1, 4, 2, 5, 1, 8, 4, 10, 2, 14, 5, 15, 1, 20, 8, 23, ...

І знову взяти часткові суми:

1, 2, 4, 5, 9, 11, 16, 17, 25, 29, 39, 41, 55, 60, 75, 76, 96, ...

Промийте, повторіть. Виявляється, цей процес сходиться. Кожен раз, коли ви повторите цей процес, більший префікс послідовності залишатиметься виправленим. Після нескінченної кількості ітерацій, ви закінчитеся з OEIS A085765 .

Забавний факт: Цей процес сходився б до тієї ж послідовності, навіть якщо ми не починалися з натуральних чисел до тих пір, поки починається початкова послідовність 1. Якщо початкова послідовність починається з будь-якої іншої x, ми отримаємо x*A085765натомість.

Змагання

Давши додатне ціле число N, виведіть цей Nелемент зведеної послідовності.

Ви можете написати програму або функцію, взявши вхід через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції та вивівши результат через STDOUT (або найближчу альтернативу), значення повернення функції або параметр функції (out).

Ви можете вибрати, чи Nбазується індекс на 0 або 1.

Випробування

Послідовність починається з:

1, 2, 4, 5, 9, 11, 16, 17, 26, 30, 41, 43, 59, 64, 81, 82, 108, 117, 147, 151, 192, 203, 246, 248, 307, 323, 387, 392, 473, 490, 572, 573, 681, 707, 824, 833, 980, 1010, 1161, 1165, 1357, 1398, 1601, 1612, 1858, 1901, 2149, 2151, 2458, 2517

Тож введення 5має спричинити вихід 9.

Ось наївна реалізація CJam, яка генерує перші Nчисла (наведені Nна STDIN). Зауважте, що ваш код повинен повертати лише цей Nелемент, а не весь префікс.


Отже, просто перевіряємо: ми виводимо третійN термін A085765 , правда?
GamrCorps

@GamrCorps Так.
Мартін Ендер

Відповіді:


7

CJam ( 23 22 байти)

Часткові суми наводяться при парних показниках фрактальної послідовності, що становить A086450 . Повторність, подана там як визначення A086450, є основою для цих реалізацій.

Використання явного "стека" (у відлякуючих лапках, оскільки це не LIFO):

{),){2md~)\),>+$)}h+,}

Демонстрація в Інтернеті

Розсічення

{         e# Anonymous function body; for clarify, pretend it's f(x)
          e# We use a stack [x_0 ... x_i] with invariant: the result is sum_j f(x_j)
  ),      e# Initialise the stack to [0 ... x]
  )       e# Uncons x, because our loop wants one value outside the stack
  {       e# Loop. Stack holds [x_0 ... x_{i-1}] x_i
    2md   e# Split x_i into (x_i)/2 and (x_i)%2
    ~)\   e# Negate (x_i)%2 and flip under (x_i)/2
    ),>   e# If x_i was even, stack now holds [x_0 ... x_{i-1}] [0 1 ... (x_i)/2]
          e# If x_i was odd, stack now holds [x_0 ... x_{i-1}] [(x_i)/2]
    +     e# Append the two arrays
    $     e# Sort to get the new stack
    )     e# Uncons the greatest element in the new stack
  }h      e# If it is non-zero, loop
          e# We now have a stack of zeroes and a loose zero
  +,      e# Count the total number of zeroes, which is equivalent to sum_j f(0)
}

У 23 байтах існує набагато ефективніший підхід із запам'ятовуванням:

{2*1a{2md~)\){j}%>:+}j}

Демонстрація в Інтернеті


1
Я впевнений, що є кілька мов, на яких було б коротше реалізувати як f(0) = 1; f(n) = f(n/2) + (n % 2 ? 0 : f(n-2)); return f(2*x), але я не можу знайти спосіб заощадити за допомогою цього підходу в CJam.
Пітер Тейлор

9

Пітон 2, 55 49 42

Я поняття не маю, що відбувається, але, здається, важко перемогти формулу Maple зі сторінки OEIS. Тут використовується індексація на основі 0.

f=lambda n,t=0:n<1or f(n/2,n%2)-~-t*f(n-1)

Завдяки @PeterTaylor на -6 байт.


Це легко оптимізувати на 6 символів, якщо ви не дбаєте про продуктивність. Частини після першого orє ефективно g(n,1) = f(n/2,n%2); g(n,0) = f(n-1) + g(n,1); тож ви можете витягнути загальне g(n,1)для отриманняf=lambda n,t=0:n<1or f(n/2,n%2)+0**t*f(n-1)
Пітер Тейлор


2

Шаблони вважаються шкідливими , 124

Fun<If<A<1>,Add<Ap<Fun<Ap<If<Sub<A<1>,Mul<I<2>,Div<A<1>,I<2>>>>,A<0>,A<0,1>>,Div<A<1>,I<2>>>>,A<1>>,Ap<A<0>,Sub<A<1>,T>>>,T>>

Це анонімна функція. Це майже так само, як і моя відповідь Python на формулу Maple на сторінці OEIS, за винятком того, що я не реалізував модуль, тому мені довелося використовувати nn / 2 * 2 замість n% 2.

Розширено:

Fun<If<
    A<1>,
    Add<
        Ap<
            Fun<Ap<
                If<
                    Sub<
                        A<1>,
                        Mul<
                            I<2>,
                            Div<A<1>,I<2> >
                        >
                    >,
                    A<0>,
                    A<0,1>
                >,
                Div<A<1>,I<2>>
            >>,
            A<1>
        >,
        Ap<
            A<0>,
            Sub<A<1>, T>
        >
    >,
    T
>> 


0

Матлаб 108 103

Я використовую той факт, що бажаний ряд є частковою сумою https://oeis.org/A086450

Але складність обчислення моєї реалізації далеко не оптимальна, навіть для цього простого повторення.

n=input('')+1;
z=zeros(1,n);z(1)=1;
for k=1:n;
z(2*k)=z(k);
z(2*k+1)=sum(z(1:k+1));
end;
disp(sum(z(1:n)))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.