Secuencia de Fibonacci de potencia alterna

24

Definición

La secuencia de Fibonacci de potencia alterna se forma de la siguiente manera.

  1. Comience con la secuencia vacía y establezca n en 1 .

  2. Compute f n , el n º no negativo número de Fibonacci , con repeticiones.
    0 es el primero, 1 es el segundo y el tercero, 2 es el cuarto. Todos los demás se obtienen sumando los dos números anteriores en la secuencia, por lo que 3 = 1 + 2 es el quinto, 5 = 2 + 3 es el sexto, etc.

  3. Si n es impar, cambie el signo de f n .

  4. Agregue 2 copias n-1 de f n a la secuencia.

  5. Incremente ny regrese al paso 2.

Estos son los primeros cien términos de la secuencia 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

Tarea

Escribir un programa completo o una función que toma un número entero positivo n como entrada y grabados o devuelve el n º término de la secuencia de APF.

Si prefiere la indexación basada en 0, también puede tomar un número entero no negativo n e imprimir o devolver el número APF en el índice n .

Este es el ; ¡que gane el código más corto en bytes!

Casos de prueba (basados ​​en 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

Casos de prueba (basados ​​en 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
Dennis
fuente
¿Hay alguna restricción para n ?
Okx
2
Siempre que su algoritmo funcione para valores arbitrariamente grandes de n , puede suponer que se ajusta a su tipo de datos.
Dennis
1
¿Tiene esto un número OEIS?
Mindwin
@Mindwin no lo hace.
Dennis

Respuestas:

12

Jalea , 5 bytes

BLCÆḞ

Pruébalo en línea!

¿Cómo?

Extender la serie de Fibonacci nuevamente a índices negativos de tal manera que la relación f(i) = f(i-2) + f(i-1)aún se mantenga:

  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 ...

Volviendo a i=0los números, son los que necesitamos repetir 2 n-1 veces, y Jelly's Fibonacci incorporado los ÆḞcalculará.

Podemos encontrar el -i(un número positivo) que necesitamos tomando la longitud de bits ny restando 1.

Dado que queremos i(un número negativo) que en su lugar puede realizar 1-bitLengthy la jalea tiene un átomo de 1-x, C, la mónada complemento.

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
Jonathan Allan
fuente
Sabía que había un camino más corto, pero no tanto, pensé que sería de 7 bytes con una forma de eliminar µy
millas
Sin embargo, su negación repetida fue inteligente, estaba buscando potencias de menos uno, lo que agrega un par de bytes, hasta que recordé los valores negativos de Fibonacci e intenté conectarlos a la mónada de Jelly.
Jonathan Allan
44
Honestamente, me sorprende que Jelly no tenga un byte incorporado para obtener la longitud binaria de un número ...
ETHproductions
22

Python 2 , 30 bytes

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

Pruébalo en línea!

Un índice.

La secuencia se sintió como un rompecabezas, algo que Dennis generó al tener una forma corta de expresarlo. Las repeticiones de la potencia de dos sugieren recurrencia mediante desplazamiento de bits (división del piso por 2). La recursión de Fibonacci de signos alternos f(n)=f(n-2)-f(n-1)se puede adaptar al desplazamiento de bits en lugar de disminuir. El caso base funciona bien porque todo se canaliza hacia n=0.

xnor
fuente
6

Mathematica, 43 36 24 bytes

Fibonacci@-Floor@Log2@#&

7 bytes guardados gracias a @GregMartin, y otros 12 gracias a @JungHwanMin.

martín
fuente
1
Puede guardar algunos bytes con Floor@Log2@#y escribiendo Fibonacci[t=...](y eliminando los espacios en el último exponente).
Greg Martin el
1
-12 bytes: Fibonacci@-Floor@Log2@#&- también Fibonaccipuede tomar argumentos negativos (se encarga del signo por usted).
JungHwan Min
5

MATL , 19 17 16 11 bytes

lOiB"yy-]x&

La entrada está basada en 1.

Pruébalo en línea! O verificar todos los casos de prueba .

Cómo funciona

Para la entrada n basada en 1 , sea m el número de dígitos en la expansión binaria de n . El n término-ésimo en la secuencia de salida es la m término-ésimo en la secuencia de Fibonacci, posiblemente con su signo cambiado.

Una idea sería iterar m veces para calcular los términos de la secuencia de Fibonacci. Esto es fácil con un for eachbucle que usa la matriz de dígitos binarios. Si la secuencia de Fibonacci se iniciara con 0 , entonces 1 como de costumbre, iterar m veces daría como resultado m + 2 términos en la pila, por lo que los dos números superiores tendrían que eliminarse. En cambio, iniciamos con 1 , luego 0 . De esa forma, los siguientes términos generados son 1 , 1 , 2 , ... y solo se necesita una eliminación.

El signo podría tratarse utilizando otro ciclo para cambiar el signo m veces. Pero eso es costoso. Es mejor integrar los dos bucles, lo que se hace simplemente restando en lugar de sumar la iteración de Fibonacci.

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
Luis Mendo
fuente
4

JavaScript (ES6), 33 bytes

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

1 indexado.

La respuesta de un puerto de xnor sería 23:

f=n=>n<1||f(n/4)-f(n/2)
ETHproducciones
fuente
4

Python 2 , 83 82 79 bytes

def f(n,a=0,b=1):
 l=bin(n)[2:]
 for _ in l:a,b=b,a+b
 return a*-(len(l)%2or-1)

Pruébalo en línea!

ovs
fuente
No se requiere espacio en blanco en or -1.
Yytsi
3

Jalea , 9 bytes

BLµ’ÆḞN⁸¡

Utiliza indexación basada en uno.

Pruébalo en línea!

Explicación

Este método funciona si su función Fibonacci solo admite argumentos no negativos.

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)
millas
fuente
3

Japt , 6 bytes

Mg1-¢l

¡Pruébalo en línea!

Cómo funciona

Como se ha mencionado en otras respuestas, la n º término en la serie de Fibonacci alterna signo es la misma que la -n ésimo término de la serie regular. n se puede encontrar tomando la longitud de bits de la entrada y restando uno; negar esto da como resultado 1 menos la longitud de bits.

Mg1-¢l
    ¢l  // Calculate the length of the input in binary.
  1-    // Subtract this from 1.
Mg      // Get the Fibonacci number at this index.
ETHproducciones
fuente
3

05AB1E , 11 10 bytes

Utiliza indexación basada en 1

La función de Fibonacci de 05AB1E devuelve números positivos de fib menos de n , lo que significa que tendríamos que generar más de lo necesario, obtener el correcto por índice y luego calcular el signo. Así que dudo que cualquier método basado en eso sea más corto que calcular los números de forma iterativa.

Se da cuenta de que podemos inicializar la pila con 1, 0invertida para manejar el caso cuando se n=1describe en la respuesta MATL de Luis Mendo .

XÎbgG‚D«`-

Pruébalo en línea!

Explicación

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
fuente
2

Perl 6 , 53 bytes

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

Implementación directa de la secuencia, la forma en que se describió.
De base cero.

smls
fuente
2

Julia 0.5 , 19 bytes

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

Pruébalo en línea!

Cómo funciona

Esto usa la misma fórmula que la respuesta Python de @ xnor . La relación de recurrencia
g (n) = g (n-2) + g (n-1) genera los términos negativos de la secuencia de Fibonacci, que son iguales a los términos positivos con signos alternos. Desde cualquier parte de una ejecución de 2 k repeticiones del mismo número, podemos elegir cualquier repetición de la ejecución anterior de 2 k-1 números y la ejecución de 2 k-2 números anteriores dividiendo el índice entre 2 y 4 .

En lugar de lo sencillo

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

Podemos redefinir un operador para nuestros propósitos. Además, f funcionará igual de bien con flotadores, así que obtenemos

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

Finalmente, si actualizamos n con una división por 4 , podemos escribir n / 2 como 2n y omitir un par de parens, lo que lleva a la definición de la función de 19 bytes en esta respuesta.

Dennis
fuente
1

J , 18 bytes

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

Utiliza indexación basada en uno. Toma un entero de entrada n > 0 y calcula floor(log2(n))al encontrar la longitud de su representación binaria y luego disminuye ese valor en uno. Luego encuentra el coeficiente floor(log2(n))-1th de la función generadora x / (1 + x - x 2 ), que es el gf para los valores de Fibonacci indexados negativamente.

Pruébalo en línea!

Explicación

(%>:-*:)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
millas
fuente