Indicizzazione dei numeri di Fibonacci estesi


21

Probabilmente hai sentito parlare dei numeri di Fibonacci. Sai, quella sequenza intera che inizia con 1, 1, e quindi ogni nuovo numero è la somma degli ultimi due?

1 1 2 3 5 8 13...

E così via. Le sfide sui numeri di Fibonacci sono piuttosto popolari qui . Ma chi dice che i numeri di Fibonacci debbano iniziare 1, 1? Perché non potevano iniziare 0, 1? Bene, ridefiniamoli per iniziare da 0:

0 1 1 2 3 5 8 13...

Ma ... Non dobbiamo nemmeno fermarci qui! Se possiamo aggiungere gli ultimi due numeri per ottenere il successivo, possiamo anche sottrarre il primo numero dal secondo numero per anteporre un nuovo numero. Quindi potrebbe iniziare con 1, 0:

1 0 1 1 2 3 5 8 13...

Possiamo anche finire con aspetti negativi:

-1 1 0 1 1 2 3 5 8 13...

E questa serie continua anche per sempre. Penso che sia interessante il modo in cui finisce per rispecchiare i normali numeri di Fibonacci, solo con ogni altro numero reso negativo:

13 -8 5 -3 2 -1 1 0 1 1 2 3 5 8 13...

Chiamiamo questa serie "Extended Fibonacci Number", o EFN . Dal momento che non c'è davvero un numero negativo evidente per iniziare questa serie, diremo che 0 appare a 0 , i numeri di Fibonacci regolari si estendono agli indici positivi e i numeri di Fibonacci negativi (semi-negativi?) negli indici negativi, in questo modo:

Indices: ...-7  -6 -5  -4 -3  -2 -1  0  1  2  3  4  5  6  7 ...
Values:  ...13  -8  5  -3  2  -1  1  0  1  1  2  3  5  8  13...

Questo porta alla sfida di oggi:

Dato un numero intero N , restituisce ogni indice in corrispondenza del quale N appare nella serie EFN .

Alcune osservazioni casuali su questo compito:

  • 1 appare più volte nella EFN rispetto a qualsiasi altro numero: [-1, 1, 2]. Nessun numero apparirà in più di 3 posti.

  • Ogni numero di Fibonacci> 1 verrà visualizzato una volta (3, 8, 21, ecc.) O due volte (2, 5, 13, ecc.)

Chiarimenti sulle regole:

  • Se abs(N)non è un numero di Fibonacci, non apparirà mai nella serie EFN , quindi è necessario generare nulla / una raccolta vuota, se possibile, o se ciò non è possibile nella propria lingua, è possibile generare un valore non numerico costante.
  • Se N appare in più punti dell'EFN , l'output non deve essere ordinato. Sebbene ogni indice debba apparire esattamente una volta.
  • Sebbene la maggior parte delle sfide di consentano di scegliere se si desidera utilizzare l'indicizzazione basata su 1 o su 0, questa sfida deve utilizzare l'indicizzazione descritta (dove 0 appare su 0).
  • È possibile eseguire l'I / O in qualsiasi formato standard.

Casi test

-13: []
-12: []
-11: []
-10: []
-9: []
-8: [-6]
-7: []
-6: []
-5: []
-4: []
-3: [-4]
-2: []
-1: [-2]
0: 0
1: [-1, 1, 2]
2: [-3, 3]
3: [4]
4: []
5: [-5, 5]
6: []
7: []
8: [6]
9: []
10: []
11: []
12: []
13: [-7, 7]

E alcuni casi di test più grandi:

89: [-11, 11]
1836311903: [46]
10000: []
-39088169: [-38]

Come al solito, vince la risposta più breve in byte!


Correlato , sebbene non un duplicato, poiché non richiede la gestione di numeri negativi o non Fibonacci.
DJMcMayhem

12
A proposito, c'è un'altra buona ragione per cui i numeri di Fibonacci dovrebbero sempre essere indicizzati in modo che $ F_0 = 0 $, anche quando si usano solo numeri di Fibonacci positivi. Questa è l'indicizzazione che consente questa meravigliosa proprietà: se $ k $ divide $ n $, allora $ F_k $ divide $ F_n $.
Greg Martin,

Risposte:


9

Haskell , 78 byte

4 byte salvati grazie a nimi

a#b=a:b#(a-b)
f 0=[0]
f a=do{(i,x)<-zip[0..a*a+1]$0#1;[-i|x==a]++[i|abs x==a]}

Provalo online!

In primo luogo abbiamo creato (#), (#)prende due parametri, ae b, e restituisce l'un elenco che inizia con ae seguita da b#(a-b). Questo crea un elenco infinito, ma poiché Haskell è pigro, non abbiamo bisogno di preoccuparci che rimanga in loop per sempre. Questo essenzialmente funziona all'indietro creando la sequenza di Fibonacci prima di una certa coppia. Ad esempio (0#1)sarebbe l'elenco di tutti i numeri di Fibonacci con indice negativo.

Da qui facciamo f. faccetta un argomento ache è il numero che stiamo cercando di trovare nella sequenza. Qui usiamo la donotazione per fare una comprensione della lista. Iniziamo prendendo i primi a*a+1elementi dell'elenco 0#11 . Poiché la funzione a*a+1cresce più velocemente dell'inverso della sequenza di Fibonacci, possiamo essere sicuri che se controlliamo all'interno di questo limite troveremo tutti i risultati. Questo ci impedisce di cercare un elenco infinito. Quindi per ogni valore xe indice i, se x==aabbiamo trovato anella metà negativa della sequenza, quindi ritorniamo -i, e se abs x==aritorniamo ianche perché il valore assoluto della metà negativa è la metà positiva, quindi l'abbiamo trovata lì.

Dal momento che questo rende l'elenco [0,0]per 0noi hardcode l'output corretto per quello.

1: questo trucco è tratto da una "pulita" risposta pulita . Lo stesso speedup si applica qui come lì, sostituendolo a*a+1con abs a+1per risparmiare un sacco di tempo.


Sostituendo ucon a#b=a:b#(a-b)più si 0#1salva un byte: provalo online!
nimi,

@nimi In realtà salva 4 byte, il tuo link tio ha 3 spazi extra.
Wheat Wizard

5

Pulito , 132 120 109 byte

import StdEnv
g n|n<2=n=g(n-1)+g(n-2)
?k=[e\\p<-[0..k*k+1],e<-if(isOdd p)([~p,p]%(0,k))[p*sign k]|g p==abs k]

Provalo online!

g :: Int -> Intè la funzione di Fibonacci.
? :: Int -> [Int]semplicemente indicizza gli elementi dell'EFN all'interno k^2+1di 0.

Per una versione che gira in un tempo ragionevole, k*k+1passa a abs k+1.


1
Quel trucco di comprensione della lista è abbastanza pulito! Salva i miei 14 byte sulla mia risposta.
Wheat Wizard


2

JavaScript (ES6),  94  93 byte

n=>(g=a=>a*a<n*n?g(b,b+=a,i++):a%n)(i=0,b=1)?[]:i&1?n<0?~n?[]:-2:i-1?[-i,i]:[-i,i,2]:n<0?-i:i

Provalo online!

-0n=0



1

Retina 0.8.2 , 104 102 byte

[1-9].*
$*
(-)?(\b1|(?>\3?)(\2))*(1)$|(0)?.*
$5$1$4$4$#2$*
-1(11)+$

^1(11)+$
-$&,$&
1+
$.&
^2$
-1,1,2

Provalo online! Spiegazione:

[1-9].*
$*

Converti in unario, a meno che l'input sia zero.

(-)?(\b1|(?>\3?)(\2))*(1)$|(0)?.*
$5$1$4$4$#2$*

Calcola l'indice di Fibonacci del valore assoluto, ma se il numero non è un numero di Fibonacci, eliminalo, a meno che non fosse zero. Questo utilizza regex di test Fibonacci di @ MartinEnder.

-1(11)+$

Elimina i numeri negativi i cui valori assoluti sono dispari numeri di Fibonacci.

^1(11)+$
-$&,$&

Aggiungi indici negativi per numeri Fibonacci dispari positivi.

1+
$.&

Converti in decimale.

^2$
-1,1,2

Aggiungi gli indici extra per 1.


1

In realtà , 34 byte

;╗3*;±kSix⌠;;AF@;1&@0>*YτD(s**╜=⌡░

La forza bruta salva la giornata

Spiegazione:

;╗3*;±kSix⌠;;AF@;1&@0>*YτD(s**╜=⌡░
;╗                                  save a copy of the input (let's call it N) to register 0 (the main way to get additional values into functions)
  3*;±                              -3*N, 3*N
      kSi                           push to list, sort, flatten (sort the two values on the stack so that they are in the right order for x)
         x                          range(min(-3*N, 3*N), max(-3*N, 3*N))
          ⌠;;AF@;1&@0>*YτD(s**╜=⌡░  filter (remove values where function leaves a non-truthy value on top of the stack):
           ;;                         make two copies of parameter (let's call it n)
             AF                       absolute value, Fib(|n|)
               @;                     bring a copy of n to the top of the stack and make another copy
                 1&                   0 if n is divisible by 2 else 1
                   @0>                1 if n is negative else 0 (using another copy of n)
                      *               multiply those two values (acts as logical AND: is n negative and not divisible by 2)
                       YτD            logical negate, double, decrement (maps [0, 1] to [1, -1])
                          (s          sign of n (using the last copy)
                            **        multiply Fib(|n|), sign of n, and result of complicated logic (deciding whether or not to flip the sign of the value for the extended sequence)
                              ╜=      push value from register 0, equality comparison (1 if value equals N else 0)

Provalo online!




0

05AB1E , 36 byte

x*ÝʒÅfIÄQ}Ii®šë1KIdiÐ`ÉiD(ì}ëD`Èi(ë¯

Ci deve essere un approccio migliore ..>.> Ci sono sei (o sette se includiamo 0) diversi scenari per questa sfida, e mi sta uccidendo ..

Provalo online o verifica tutti i casi di test .

Spiegazione:

x            # Create a list in the range [0, (implicit) input * input * 2]
   ʒ     }     # Filter this list by:
    Åf         #  Where the Fibonacci value at that index
      IÄQ      #  Is equal to the absolute value of the input
Ii             # If the input is exactly 1:
  ®š           #  Prepend -1 to the list
ë              # Else:
 1K            #  Remove all 1s (only applies to input -1)
 Idi           #  If the input is non-negative:
    Ð`Éi   }   #   If the found index in the list is odd:
        D    #    Prepend its negative index to the list
   ë           #  Else (the input is negative):
    Di       #   If the found index in the list is even:
        (      #    Negate the found index
       ë       #   Else (found index is odd):
        ¯      #    Push an empty array
               # (Output the top of the stack implicitly as result)

Alcuni esempi passo-passo:

Input:  Filtered indices:  Path it follows (with actions) and result:

-8      [6]                NOT 1 → neg → even index → negate index: [-6]
-5      [5]                NOT 1 → neg → odd index → push empty array: []
-1      [1,2]              NOT 1 → (remove 1) neg → even remaining index: negate index: [-2]
0       [0]                NOT 1 → even index → negate index: [0]    
1       [1,2]              1 → prepend -1: [-1,1,2]
5       [5]                NOT 1 → non-neg → odd index → Prepend neg index: [-5,5]
8       [6]                NOT 1 → non-neg → even index → (nothing): [6]


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.