Последовательность Фибоначчи с переменной мощностью

24

Определение

Последовательность Фибоначчи с переменной мощностью формируется следующим образом.

  1. Начните с пустой последовательности и установите n в 1 .

  2. Вычислите f n , n- е неотрицательное число Фибоначчи , с повторениями.
    0 - первое, 1 - второе и третье, 2 - четвертое. Все остальные получаются суммированием двух предыдущих чисел в последовательности, поэтому 3 = 1 + 2 - это пятое, 5 = 2 + 3 - это шестое и т. Д.

  3. Если n нечетно, измените знак f n .

  4. Добавьте 2 n-1 копии f n к последовательности.

  5. Увеличьте n и вернитесь к шагу 2.

Это первые сто членов последовательности APF.

 0  1  1 -1 -1 -1 -1  2  2  2  2  2  2  2  2 -3 -3 -3 -3 -3 -3 -3 -3 -3 -3
-3 -3 -3 -3 -3 -3  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5
 5  5  5  5  5  5  5  5  5  5  5  5  5 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8
-8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8

задача

Напишите полную программу или функцию, которая принимает положительное целое число n в качестве входных данных и печатает или возвращает n- й член последовательности APF.

Если вы предпочитаете индексирование на основе 0, вы можете взять неотрицательное целое число n и напечатать или вернуть номер APF по индексу n .

Это ; пусть победит самый короткий код в байтах!

Контрольные примеры (на основе 1)

    1 ->    0
    2 ->    1
    3 ->    1
    4 ->   -1
    7 ->   -1
    8 ->    2
  100 ->   -8
  250 ->   13
  500 ->  -21
 1000 ->   34
11111 ->  233
22222 -> -377
33333 ->  610

Контрольные примеры (на основе 0)

    0 ->    0
    1 ->    1
    2 ->    1
    3 ->   -1
    6 ->   -1
    7 ->    2
   99 ->   -8
  249 ->   13
  499 ->  -21
  999 ->   34
11110 ->  233
22221 -> -377
33332 ->  610
Деннис
источник
Есть ли какие-то ограничения для n ?
Okx
2
Пока ваш алгоритм работает для сколь угодно больших значений n , вы можете предполагать, что он вписывается в ваш тип данных.
Деннис
1
У этого есть номер OEIS?
Mindwin
@ Миндвин Это не так.
Деннис

Ответы:

12

Желе , 5 байт

BLCÆḞ

Попробуйте онлайн!

Как?

Расширяя ряд Фибоначчи обратно в отрицательные индексы, так что отношение f(i) = f(i-2) + f(i-1)остается в силе:

  i   ...   -8  -7  -6  -5  -4  -3  -2  -1   0   1   2   3   4   4   5 ...
f(i)  ...  -21  13  -8   5  -3   2  -1   1   0   1   1   2   3   5   8 ...

Возвращаясь к i=0числам, мы должны повторить их 2 n-1 раз, и встроенная функция Фибоначчи Джелли ÆḞвычислит их.

Мы можем найти -i(положительное число), которое нам нужно, взяв длину в битах nи вычтя 1.

Так как мы хотим i(отрицательное число) , мы можем вместо выполнения 1-bitLengthи желе имеет атом для 1-x, C, комплемента монады.

BLCÆḞ - Main link: n               e.g.  500
B     - convert n to a binary list      [1,1,1,1,1,0,1,0,0]
 L    - get the length                   9
  C   - complement                      -8
   ÆḞ - Fibonacci                       -21
Джонатан Аллан
источник
Я знал, что есть более короткий путь, но не очень, думал, что это будет 7 байт с возможностью удаления µи
миль
Ваше повторное отрицание было умным, хотя, я смотрел на степени минус один, который добавляет пару байтов, пока я не вспомнил об отрицательных значениях Фибоначчи и не попытался вставить их в монаду Желе.
Джонатан Аллан
4
Честно говоря, я удивлен, что у Jelly нет однобайтовой встроенной функции для получения двоичной длины числа ...
ETHproductions
22

Python 2 , 30 байт

f=lambda n:n<1or f(n/4)-f(n/2)

Попробуйте онлайн!

Один индексированные.

Последовательность походила на головоломку, то, что Деннис создал, имея короткий способ выразить это. Степень двойного повторения предполагает повторение путем сдвига битов (деление на пол на 2). f(n)=f(n-2)-f(n-1)Рекурсию Фибоначчи с переменным знаком можно адаптировать к сдвигу битов вместо уменьшения. Базовый вариант работает хорошо, потому что все направлено на n=0.

XNOR
источник
6

Mathematica, 43 36 24 байта

Fibonacci@-Floor@Log2@#&

Благодаря @GregMartin сохранено 7 байт, а еще 12 - @JungHwanMin.

Мартин
источник
1
Вы можете сохранить несколько байтов с помощью Floor@Log2@#, и написав Fibonacci[t=...](и удалив пробелы в последнем показателе).
Грег Мартин
1
-12 байт: Fibonacci@-Floor@Log2@#&- Fibonacciможет принимать и отрицательные аргументы (заботится о знаке за вас).
JungHwan Мин
5

MATL , 19 17 16 11 байт

lOiB"yy-]x&

Вход основан на 1.

Попробуйте онлайн! Или проверьте все тестовые случаи .

Как это работает

Для ввода n , основанного на 1 , пусть m будет количеством цифр в двоичном расширении n . П -й член в выходной последовательности является м -й член последовательности Фибоначчи, возможно , с его знак изменился.

Одной из идей было бы повторение m раз для вычисления членов последовательности Фибоначчи. Это легко сделать с помощью for eachцикла, использующего массив двоичных цифр. Если бы последовательность Фибоначчи была инициализирована с 0 , а затем с 1, как обычно, итерация m раз привела бы к m + 2 слагаемым в стеке, поэтому два верхних числа пришлось бы удалить. Вместо этого мы инициализируем 1 , затем 0 . Таким образом, следующие сгенерированные термины - 1 , 1 , 2 , ... и требуется только одно удаление.

Знак может быть обработан с помощью другого цикла, чтобы изменить знак m раз. Но это дорого. Лучше объединить два цикла, что делается простым вычитанием, а не добавлением в итерацию Фибоначчи.

l       % Push 1
O       % Push 0
iB      % Input converted to binary array
"       % For each
  yy    %   Duplicate top two elements
  -     %   Subtract. This computes the new Fibonacci term with the sign changes
]       % End
x       % Delete top number
&       % Specify that implicit display should take only one input
        % Implicitly display the top of the stack
Луис Мендо
источник
4

JavaScript (ES6), 33 байта

f=(n,p=1,c=0)=>n?-f(n>>1,c,p+c):p

1-индексироваться.

Порт ответа xnor будет 23:

f=n=>n<1||f(n/4)-f(n/2)
ETHproductions
источник
3

Желе , 9 байт

BLµ’ÆḞN⁸¡

Использует индексирование на основе одного.

Попробуйте онлайн!

объяснение

Этот метод работает, если ваша функция Фибоначчи поддерживает только неотрицательные аргументы.

BLµ’ÆḞN⁸¡  Input: integer n
B          Binary digits of n
 L         Length. len(bin(2)) = floor(log2(n)))
  µ        Start new monadic chain on x = len(bin(2))
   ’       Decrement
    ÆḞ     Get Fibonacci(x-1)
       ⁸¡  Repeat x times on that
      N      Negate.
           Return Fibonacci(x-1) if x is even else -Fibonacci(x-1)
миль
источник
3

Japt , 6 байт

Mg1-¢l

Проверьте это онлайн!

Как это работает

Как уже упоминалось в других ответах, то п - й член в знакопеременным ряда Фибоначчи является таким же , как -п - й член в очередной серии. n можно найти, взяв длину в битах и ​​вычтя ее; отрицание этого приводит к 1 минус битовая длина.

Mg1-¢l
    ¢l  // Calculate the length of the input in binary.
  1-    // Subtract this from 1.
Mg      // Get the Fibonacci number at this index.
ETHproductions
источник
3

05AB1E , 11 10 байт

Использует индексирование на основе 1

05AB1E Функция Фибоначчи возвращает положительные числа Фибоначала меньше n , что означает, что нам нужно сгенерировать больше, чем необходимо, получить правильное число по индексу и затем вычислить знак. Поэтому я сомневаюсь, что любой метод, основанный на этом, будет короче, чем итерационный расчет чисел.

Использует осознание того, что мы можем инициализировать стек с помощью 1, 0обращения, чтобы обрабатывать случай, n=1как описано в ответе Луиса Мендо на MATL .

XÎbgG‚D«`-

Попробуйте онлайн!

объяснение

X             # push 1
 Î            # push 0 and input
  b           # convert input to binary
   g          # get length of binary number
    G         # for N in [1...len(bin(input))-1] do:
     ‚        # pair the top 2 elements of the stack in a list
      D       # duplicate the list 
       «      # concatenate the 2 lists together
        `     # split into separate elements on the stack
         -    # subtract the top 2 elements
Emigna
источник
2

Perl 6 , 53 байта

{flat(((0,1,*+*...*)Z*|<-1 1>xx*)Zxx(1,2,4...*))[$_]}

Прямая реализация последовательности, как она была описана.
Нулевой основе.

SMLS
источник
2

Юлия 0,5 , 19 байт

!n=n<1||!(n/=4)-!2n

Попробуйте онлайн!

Как это работает

При этом используется та же формула, что и в ответе Python @ xnor . Отношение рекуррентности
g (n) = g (n-2) + g (n-1) порождает отрицательные члены последовательности Фибоначчи, которые равняются положительным членам с чередующимися знаками. Из любого места в серии из 2 k повторений с одним и тем же номером мы можем выбрать любое повторение предыдущего набора из 2 k-1 чисел и набора из 2 k-2 чисел перед делением путем деления индекса на 2 и 4 .

Скорее, чем просто

f(n)=n<1||f(n÷4)-f(n÷2) # 25 bytes

мы можем переопределить оператор для наших целей. Кроме того, f будет работать так же хорошо с плавающей точкой, поэтому мы получаем

!n=n<1||!(n/4)-!(n/2)   # 21 bytes

Наконец, если мы обновим n с делением на 4 , мы можем записать n / 2 как 2n и опустить пару символов, что приведет к 19-байтовому определению функции в этом ответе.

Деннис
источник
1

J , 18 байт

(%>:-*:)t.@<:@#@#:

Использует индексацию по одному. Принимает входное целое число n > 0 и вычисляет floor(log2(n)), находя длину его двоичного представления, а затем уменьшает это значение на единицу. Затем она находит floor(log2(n))-1й коэффициент порождающей функции х / (1 + х - x 2 ), который является gf для отрицательно-индексированных значений Фибоначчи.

Попробуйте онлайн!

объяснение

(%>:-*:)t.@<:@#@#:  Input: integer n
                #:  Binary
              #@    Length
           <:@      Decrement
(      )            The generating function x/(1+x-x^2)
  >:                  Increment x
     *:               Square x
    -                 Subtract
 %                    Divide x by previous
        t.          Get series coefficient at the index given by previous value
миль
источник