I numeri di Lucas-nacci


19

sfondo

Quasi tutti hanno familiarità con i numeri di Fibonacci F(n) :

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

Questi sono formati dalla funzione di ricorsione F(n) = F(n-1) + F(n-2)con F(0)=0e F(1)=1. A000045

Una sequenza strettamente correlata sono i numeri di Lucas L(m) :

2, 1, 3, 4, 7, 11, 18, 29 ...

Questi sono formati dalla funzione di ricorsione L(m) = L(m-1) + L(m-2)con L(0)=2e L(1)=1. A000032

Possiamo alternare le due sequenze basate su indici pari / dispari, con la costruzione
A(x) = F(x)if x mod 2 = 0e A(x) = L(x)altrimenti. Ad esempio, A(4)è uguale a F(4)da 4 mod 2 = 0. Chiameremo questa sequenza i numeri di Lucas-Nacci , A(x):

0, 1, 1, 4, 3, 11, 8, 29, 21, 76 ...

Questo può essere formato dalla funzione ricorsione A(x) = 3*A(x-2) - A(x-4)con A(0)=0, A(1)=1, A(2)=1e A(3)=4. A005013

Sfida

Dato input n, emette la sequenza di n+1numeri fino a e incluso A(n)come descritto sopra. Vince il minor numero di byte (o equivalenti a byte, come per LabVIEW , determinati individualmente su Meta).

Ingresso

Un singolo numero intero non negativo n.

Produzione

Un elenco di numeri che corrispondono alla sottosequenza dei numeri di Lucas-nacci da A(0)a A(n). L'elenco deve essere in ordine sequenziale come descritto sopra.

Regole

  • Si applicano le regole standard del code-golf e le restrizioni di scappatoia .
  • Si applicano le regole standard di input / output .
  • Il numero di input può essere in qualsiasi formato adatto: unario o decimale, letto da STDIN, argomento della riga di comando o della funzione, ecc. - a scelta.
  • L'output può essere stampato su STDOUT o restituito come risultato della chiamata di funzione. Se stampati, devono essere inclusi delimitatori adatti per differenziare i numeri (separati da spazio, separati da virgola, ecc.).
  • Inoltre, se l'output su STDOUT, gli spazi bianchi circostanti, la nuova riga finale, ecc. Sono tutti facoltativi.
  • Se l'input è un numero intero o un numero intero negativo, il programma può fare qualsiasi cosa o nulla, poiché il comportamento non è definito.

Esempi

Input -> Output
0 -> 0
5 -> 0, 1, 1, 4, 3, 11
18 -> 0, 1, 1, 4, 3, 11, 8, 29, 21, 76, 55, 199, 144, 521, 377, 1364, 987, 3571, 2584

Newline è considerato un delimitatore accettato?
corsiKa

@corsiKa Certo, va bene.
AdmBorkBork,

Risposte:


9

Gelatina, 12 byte

;2U+¥Ð¡-,1ZḢ

Provalo online!

sfondo

Possiamo estendere F e L a -1 definendo F (-1) = 1 e L (-1) = -1. Ciò è coerente con la funzione ricorsiva.

Il nostro programma inizia con

-1  1
 0  2

In ogni passaggio, per formare la coppia successiva, invertiamo l'ultima coppia e la aggiungiamo alla penultima coppia. Per esempio:

[0, 2] U+¥ [-1, 1] -> [2, 0] + [-1, 1] -> [1, 1]

Se continuiamo questo processo per qualche altro passaggio, otteniamo

-1  1
 0  2
 1  1
 1  3
 4  2
 3  7
11  5

La sequenza di Lucas-nacci è semplicemente la colonna di sinistra.

Come funziona

;2U+¥Ð¡-,1ZḢ  Niladic link. No implicit input.
              Since the link doesn't start with a nilad, the argument 0 is used.

;2            Concatenate the argument with 2, yielding [0, 2].
       -,1    Yield [-1, 1]. This is [L(-1), F(-1)].
    ¥         Create a dyadic chain of the two atoms to the left:
  U             Reverse the left argument.
   +            Add the reversed left argument and the right one, element-wise.
     С       For reasons‡, read a number n from STDIN.
              Repeatedly call the dyadic link U+¥, updating the right argument with
              the value of the left one, and the left one with the return value.
              Collect all intermediate results.
          Z   Zip the list of results, grouping the first and seconds coordinates.
           Ḣ  Head; select the list of first coordinates.

С sbircia i due collegamenti a sinistra: 2e U+¥. Poiché quello più a sinistra è un nilad, non può essere il corpo del loop. Pertanto, U+¥viene utilizzato come body e un numero viene letto dall'input. Poiché non ci sono argomenti della riga di comando, quel numero viene letto da STDIN.


2
Ho l'impressione che tu faccia questo tipo di cose (giocare a golf in Jelly) per vivere. Il che mi rende terrorizzato.
Draco18s

24
Se qualcuno ordina come golf (codice) per vivere, per favore, chiamami in chat. Chiedere un amico ...
Martin Ender,

2
Quindi, in sostanza, stai solo calcolando entrambe le sequenze, ma invertendo ad ogni passaggio, che cambia efficacemente tra le sequenze.
Neil,

1
@Neil Sì, esattamente. Evita in seguito l'interlacciamento delle sequenze, che è leggermente più lungo.
Dennis,

6

CJam, 21 20 byte

Grazie a Sp3000 per il salvataggio di 1 byte.

TXX4ri{1$3*4$-}*?;]p

Provalo qui.

Spiegazione

Utilizza semplicemente la ricorrenza indicata nelle specifiche della sfida.

TXX4 e# Push 0 1 1 4 as base cases.
ri   e# Read input and convert to integer N.
{    e# Run this N times...
  1$ e#   Copy a(n-2).
  3* e#   Multiply by 3.
  4$ e#   Copy a(n-4).
  -  e#   Subtract.
}*
?;   e# Discard the last three values, using a ternary operation and popping the result.
]p   e# Wrap the rest in an array and pretty-print it.

1
Chi (o cosa) è Sp3000 che ringrazi per ogni risposta?
CJ Dennis,


5
@CJDennis Alcuni sostengono che sia il più grande golfista Python che abbia mai vissuto. Alcuni dicono che vive in una capanna isolata sulla cima di una montagna, costruita con un numero minimo di tronchi. Alcuni dicono che è la voce nella parte posteriore delle nostre teste, che ci assilla quando pubblichiamo soluzioni che possono essere ulteriormente giocate a golf. Ma la maggior parte di noi dice solo che è l'utente il cui profilo è stato collegato a Martin.
Mego

6

Perl 6, 42 byte

{(0,1,1,4,{$^b;$^d;3*$^c-$^a}...*)[0..$_]}

uso

> my &f = {(0,1,1,4,{$^b;$^d;3*$^c-$^a}...*)[0..$_]}
-> ;; $_? is raw { #`(Block|184122176) ... }
> f(0)
(0)
> f(5)
(0 1 1 4 3 11)
> f(18)
(0 1 1 4 3 11 8 29 21 76 55 199 144 521 377 1364 987 3571 2584)

1
La lambda più chiara che mi è venuta in mente è{( (0,1,*+*...*) Z (2,1,*+*...*) ).flat.rotor( 1=>2, 1=>0 )[ 0..$_ ].flat}
Brad Gilbert b2gills

Dato che il testo esatto è "dato n", si potrebbe risparmiare un byte con: (0,1,1,4,{$^b;$^d;3*$^c-$^a}...*)[^(n+1)].
Raiph,

6

Haskell, 59 , 57 , 56 , 52 , 51 byte

l a=2*mod a 2:scanl(+)1(l a)
f n=[l i!!i|i<-[0..n]]

Definizione della serie adattata da questa risposta .

Meno golf:

fibLike start = start : scanl (+) 1 (fibLike start)
whichStart i = (2*mod i 2)
lucasNacci i = fibLike (whichStart i) !! i
firstN n = [ lucasNacci i | i <- [0..n]]

fibLike startfornisce una lista infinita, definito: f(0)=start, f(1)=1, f(n)=f(n-1) + f(n-2). whichStart irestituisce 2 per input dispari (serie Lucas) o 0 per pari (serie Fibonacci). lucasNacci idà il numero di Lucas-nacci. firstN nmappe sopra l'elenco.

Un byte salvato da Boomerang.


1
Penso che puoi ottenere un altro byte spostandoti 2*mod i 2in lpoi puoi rimuovere la parentesi. In questo modo: l a=2*mod a 2:scanl(+)1(l a)ef n=[l i!!i|i<-[0..n]]
basile-henry

@ Boomerang Yup, funziona. Grazie
Michael Klein,

5

ES6, 65 byte

n=>[...Array(n)].map(_=>a.shift(a.push(a[2]*3-a[0])),a=[0,1,1,4])

Utilizza la relazione di ricorrenza fornita nella domanda.


5

Retina , 70 62 59 byte

1
¶$`1
m`^(11)*1$
$&ff
m`$
 f
+`1(f*) (f*)
$2 $2$1
 f*

f
1

Provalo online

  • L'input è in base unaria, n 1 s .
  • 1? $`¶- Crea una riga per ogni numero da 0 a n : , 1, 11, 111, 1111, ...
  • m`^(11)*1$ $&ff- Aggiungi ffa linee dispari. Questo eseguirà il seeding della funzione con L (0) = 2.
  • m`$  f- Aggiungi  fa tutte le righe (notare lo spazio). Questo semina la funzione con 0 e 1 per i numeri di Fibonacci e 2 e 1 per i numeri di Lucas.
  • +`1(f*) (f*) $2 $2$1 - Loop: calcola F (n + 1) = F (n) + F (n-1) mentre ci sono ancora 1 s.
  •  f*   - Rimuovere F (n + 1) dalla fine di ogni riga.
  • Sostituisci fs indietro a 1 s. Se questo non è necessario e possiamo rimanere con fs, la lunghezza è di soli 55 byte.

5

Oracle SQL 11.2, 218 216 201 byte

WITH v(a,b,c,d,i)AS(SELECT 0,1,1,4,3 FROM DUAL UNION ALL SELECT b,c,d,3*c-a,i+1 FROM v WHERE i<:1)SELECT SIGN(LEVEL-1) FROM DUAL WHERE LEVEL-1<=:1 CONNECT BY LEVEL<4UNION ALL SELECT d FROM v WHERE:1>2;

Un-golfed

WITH v(a,b,c,d,i) AS 
(
  SELECT 0,1,1,4,3 FROM DUAL 
  UNION ALL 
  SELECT b,c,d,3*c-a,i+1 FROM v WHERE i<:1
)
SELECT SIGN(LEVEL-1) FROM DUAL WHERE LEVEL-1<=:1 CONNECT BY LEVEL<4
UNION ALL SELECT d FROM v WHERE:1>2;

Sono riuscito a guadagnare qualche byte usando (abusando?) La funzione SIGN per generare i primi 3 elementi della sequenza.


3

Japt, 25 22 21 byte

Uò £MgXf2)+X%2*Mg°X)r

Provalo online!

sfondo

È in qualche modo difficile creare una sequenza di Fibonacci in Japt, ma abbiamo un built-in Mgper farlo per noi. Tuttavia, questo ci dà solo la sequenza di Fibonacci, non la sequenza di Lucas. Possiamo realizzare abbastanza facilmente la sequenza di Lucas usando questo trucco:

N    F(N-1)  F(N+1)  F(N-1)+F(N+1)
0    1       1       2
1    0       1       1
2    1       2       3
3    1       3       4
4    2       5       7
5    3       8       11
6    5       13      18
7    8       21      29

Come puoi vedere, F(N-1) + F(N+1)è uguale L(N)per tutti N. Tuttavia, poiché abbiamo solo bisogno dei numeri di Lucas sugli indici dispari, possiamo combinare le due formule in una:

N    N-N%2  N+N%2    F(N-N%2)  F(N+N%2)*(N%2)  F(N-N%2)+F(N+N%2)*(N%2)
0    0      0        0         0               0
1    0      2        0         1               1
2    2      2        1         0               1
3    2      4        1         3               4
4    4      4        3         0               3
5    4      6        3         8               11
6    6      6        8         0               8
7    6      8        8         21              29

Come funziona

Uò £  MgX-1 +X%2*Mg° X)r
Uò mX{MgX-1 +X%2*Mg++X)r

             // Implicit: U = input integer
Uò mX{       // Create the inclusive range [0..U], and map each item X to:
MgXf2)+      //  Floor X to a multiple of 2, calculate this Fibonacci number, and add:
+X%2*Mg++X)  //  Calculate the (X+1)th Fibonacci number and multiply by X%2.
)r           //  Round the result. (The built-in Fibonacci function returns
             //  a decimal number on higher inputs.)

3

Mathematica, 52 51 byte

If[#>2,3#0[#-2]-#0[#-4],#-If[#>1,1,0]]&/@0~Range~#&

Idea molto simile a quella di Martin, ho passato un po 'di tempo a cercare un modo più breve di definire i "casi base" per la funzione. L'interpolazione polinomiale è stata un fallimento, quindi ho optato per questo, usando l'estensione in negativi per produrre una definizione piuttosto breve.


2

Mathematica, 56 byte

f@0=0
f@1=f@2=1
f@3=4
f@n_:=3f[n-2]-f[n-4];
f/@0~Range~#&

Implementazione molto semplice. Definisce una funzione di supporto fe quindi valuta una funzione senza nome che si applica fa un intervallo per ottenere tutti i risultati. Questo sembra inutilmente ingombrante.

Una singola funzione senza nome sembra essere più lunga di un byte:

Switch[#,0,0,1,1,2,1,3,4,_,3#0[#-2]-#0[#-4]]&/@0~Range~#&

2

MATL , 17 18 byte

0ll4i:"y3*5$y-](x

Traduzione quasi diretta della risposta CJam di Martin .

Provalo online!

0ll4       % push first four numbers: 0,1,1,4
i:         % input n and generate array [1,2,...,n]
"          % for loop. Repeat n times
  y        % copy second-top element from stack
  3*       % multiply by 3
  5$y      % copy fifth-top element from stack
  -        % subtract. This is the next number in the sequence
]          % end loop
(x         % indexing operation and delete. This gets rid of top three numbers

2

Brachylog , 51 byte

:0re{:4<:[0:1:1:4]rm!.|-4=:1&I,?-2=:1&*3-I=.}w,@Sw\

Questo prende un numero come input e stampa su STDOUT l'elenco, con spazi che separano ciascun numero.

Spiegazione

§ Main predicate

:0re{...}               § Enumerate integers between 0 and the Input, pass the integer 
                        § as input to sub-predicate 1      
         w,@Sw          § Write sub-predicate 1's output, then write a space
              \         § Backtrack (i.e. take the next integer in the enumeration)


§ Sub-predicate 1

:4<                     § If the input is less than 4
   :[0:1:1:4]rm!.       § Then return the integer in the list [0,1,1,4] at index Input

|                       § Else

-4=:1&I,                § I = sub_predicate_1(Input - 4)
        ?-2=:1&*3-I=.   § Output = sub_predicate_1(Input - 2) * 3 - I

Il taglio !nella prima regola del sub-predicato 1 è necessario in modo che quando torniamo indietro ( \), non finiamo in un ciclo infinito in cui l'interprete proverà la seconda regola per un input inferiore a 4.


2

Mathematica, 41 byte

LinearRecurrence[{0,3,0,-1},{0,1,1,4},#]&

2

Groovy, 50 byte

x={a,b=0,c=1,d=1,e=4->a<0?:[b,x(a-1,c,d,e,3*d-b)]}

Questo definisce la funzione x, che accetta n come primo argomento e ha il caso base dei primi quattro numeri nella sequenza di Fibocas come argomenti predefiniti per il resto della funzione.

a qui è n. b, c, d ed e sono i successivi quattro elementi della sequenza.

Decrementa n e ricorre fino a quando n è inferiore a zero: quando ricorre, aggiunge al valore di ritorno finale il primo elemento nella sequenza corrente. I nuovi valori per i successivi quattro elementi nella sequenza vengono dati alla chiamata ricorsiva: gli ultimi tre elementi vengono spostati per essere i primi tre e un nuovo quarto elemento viene generato da due degli elementi precedenti usando 3 * db.

Delimita i nuovi valori con gli annidamenti degli elenchi, poiché groovy può restituire più valori inserendoli in un elenco, quindi ogni chiamata restituisce il primo elemento corrente e il risultato della ricorsione, che sarà il proprio elenco.



1

Piloni , 19

Questa è una traduzione abbastanza diretta dell'approccio di Martin.

0114{@-4@-33*-,i}=4

Come funziona:

0114    # Push 0, 1, 1, 4 to the stack.
{       # Start a for loop.
 @-4    # Get the stack element at index -4
 @-3    # Get the stack element at index -3
 3      # Push 3 to the stack.
 *      # Multiply the top two elements of the stack.
 -      # Subtract the top two elements of the stack.
  ,     # Switch to loop iterations.
 i      # Get command line args.
}       # End for loop.
=4      # Discard the top 4 elements of the stack.

1

DUP , 32 byte

[a:0 1$4[a;1-$a:][1ø3*4ø-]#%%]

Try it here!

Un lambda anonimo che lascia una sequenza di numeri in pila. Uso:

8[a:0 1$4[a;1-$a:][1ø3*4ø-]#%%]!

Spiegazione

[                              {start lambda}
 a:                            {save input number to a}
   0 1$4                       {base cases to get us started}
        [       ][       ]#    {while loop}
         a;1-$a:               {a--, check if a>0}
                  1ø3*4ø-      {3*stack[n-2]-stack[n-4]}

                           %%  {discard top 2 stack items}
                             ] {end lambda}

1

Python 2, 71 byte

def a(n,x=0,y=1,z=2,w=1,p=0):
 if~n:print[x,z][p];a(n-1,y,x+y,w,z+w,~p)

Questo sembra decisamente troppo lungo. Tuttavia, mi ha fatto piacere poter usare l' notoperatore bit per bit ... due volte. Una volta come una specie di parità capovolgi avanti e indietro e una volta per terminare la ricorsione quando nraggiunge -1.

La variabile psarà sempre o 0o -1, quindi si alternerà tra le voci 0o -1dell'elenco. (Scegliere la voce -1di un elenco Python significa scegliere l'ultimo elemento.)


1

Programmazione meta template C ++, 130 byte

template<int X>struct L{enum{v=3*L<X-2>::v-L<X-4>::v};};
#define D(X,A) template<>struct L<X>{enum{v=A};};
D(0,0)D(1,1)D(2,1)D(3,4)

Le definizioni ricorsive in qualche modo piangono per C ++ TMP, utilizzo:

L<x>::v

con l' xessere A(x)come ti piace.

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.