Nomor Lucas-nacci


19

Latar Belakang

Sebagian besar orang akrab dengan angka Fibonacci F(n) :

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

Ini dibentuk oleh fungsi rekursi F(n) = F(n-1) + F(n-2)dengan F(0)=0dan F(1)=1. A000045

Urutan yang terkait erat adalah angka Lucas L(m) :

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

Ini dibentuk oleh fungsi rekursi L(m) = L(m-1) + L(m-2)dengan L(0)=2dan L(1)=1. A000032

Kita dapat bergantian antara dua urutan berdasarkan indeks genap / ganjil, dengan konstruksi
A(x) = F(x)jika x mod 2 = 0dan A(x) = L(x)sebaliknya. Misalnya, A(4)sama dengan F(4)sejak 4 mod 2 = 0. Kami akan memanggil urutan ini Nomor Lucas-nacci , A(x):

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

Hal ini dapat dibentuk oleh fungsi rekursi A(x) = 3*A(x-2) - A(x-4)dengan A(0)=0, A(1)=1, A(2)=1, dan A(3)=4. A005013

Tantangan

Input yang diberikan n, output urutan n+1angka hingga dan termasuk A(n)seperti yang dijelaskan di atas. Bytes paling sedikit (atau byte-setara, seperti untuk LabVIEW , sebagaimana ditentukan secara individual pada Meta) menang.

Memasukkan

Bilangan bulat non-negatif tunggal n.

Keluaran

Daftar nomor yang sesuai dengan urutan nomor Lucas-nacci dari A(0)hingga A(n). Daftar harus berurutan seperti dijelaskan di atas.

Aturan

  • Aturan standar kode golf dan pembatasan lubang berlaku.
  • Aturan input / output standar berlaku.
  • Nomor input dapat dalam format yang sesuai: unary atau desimal, baca dari STDIN, argumen fungsi atau baris perintah, dll. - pilihan Anda.
  • Output dapat dicetak ke STDOUT atau dikembalikan sebagai hasil dari panggilan fungsi. Jika dicetak, pembatas yang sesuai untuk membedakan angka harus dimasukkan (dipisahkan spasi, dipisahkan koma, dll.).
  • Selain itu, jika output ke STDOUT, spasi putih di sekitar, trailing newline, dll. Semuanya opsional.
  • Jika inputnya adalah non-integer atau integer negatif, program dapat melakukan apa saja atau tidak sama sekali, karena perilaku tidak terdefinisi.

Contohnya

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

Apakah baris baru dianggap sebagai pembatas yang diterima?
corsiKa

@corsiKa Tentu, tidak apa-apa.
AdmBorkBork

Jawaban:


9

Jelly, 12 byte

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

Cobalah online!

Latar Belakang

Kita dapat memperluas F dan L ke -1 dengan mendefinisikan F (-1) = 1 dan L (-1) = -1. Ini konsisten dengan fungsi rekursif.

Program kami dimulai dengan

-1  1
 0  2

Di setiap langkah, untuk membentuk pasangan berikutnya, kami membalikkan pasangan terakhir dan menambahkannya ke pasangan kedua dari belakang. Sebagai contoh:

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

Jika kami melanjutkan proses ini untuk beberapa langkah lagi, kami mendapatkannya

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

Urutan Lucas-nacci hanyalah kolom kiri.

Bagaimana itu bekerja

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

С mengintip dua tautan ke kiri: 2dan U+¥. Karena yang paling kiri adalah nilad, itu tidak bisa menjadi badan loop. Oleh karena itu, U+¥digunakan sebagai badan dan angka dibaca dari input. Karena tidak ada argumen baris perintah, angka itu dibaca dari STDIN.


2
Saya mendapat kesan bahwa Anda melakukan hal semacam ini (bermain golf di Jelly) untuk mencari nafkah. Yang membuat saya takut.
Draco18s

24
Jika ada yang memilah cara bermain golf (kode) untuk mencari nafkah, harap ping saya dalam obrolan. Meminta teman ...
Martin Ender

2
Jadi pada dasarnya Anda hanya menghitung kedua urutan, tetapi membalikkan pada setiap langkah, yang secara efektif beralih di antara urutan.
Neil

1
@Neil Ya, tepatnya. Ini menghindari interleaving urutan setelahnya, yang sedikit lebih lama.
Dennis

6

CJam, 21 20 byte

Terima kasih kepada Sp3000 untuk menghemat 1 byte.

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

Uji di sini.

Penjelasan

Cukup gunakan perulangan yang diberikan dalam spec tantangan.

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
Siapa (atau apa) Sp3000 yang Anda ucapkan terima kasih atas setiap jawaban?
CJ Dennis


5
@ CJDennis Beberapa mengatakan dia adalah pegolf Python terhebat yang pernah hidup. Beberapa mengatakan dia tinggal di sebuah pondok terpencil di atas gunung, dibangun dari sedikit kayu gelondongan. Ada yang bilang dia adalah suara di belakang kepala kita, yang mengganggu kita ketika kita memposting solusi yang bisa bermain golf lebih lanjut. Tetapi kebanyakan dari kita hanya mengatakan dia adalah pengguna yang profilnya ditautkan Martin.
Mego

6

Perl 6, 42 byte

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

pemakaian

> 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
Lambda paling jelas yang saya buat adalah{( (0,1,*+*...*) Z (2,1,*+*...*) ).flat.rotor( 1=>2, 1=>0 )[ 0..$_ ].flat}
Brad Gilbert b2gills

Mengingat bahwa kata-kata yang tepat adalah "diberikan n", Anda bisa menghemat byte dengan: (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]]

Definisi seri diadaptasi dari jawaban ini .

Kurang bermain 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 startmemberikan daftar yang tak terbatas, yang didefinisikan: f(0)=start, f(1)=1, f(n)=f(n-1) + f(n-2). whichStart imengembalikan 2 untuk input ganjil (seri Lucas) atau 0 untuk genap (seri Fibonacci). lucasNacci imemberi nomor Lucas-nacci ke-i. firstN npeta di atas daftar.

Satu byte disimpan oleh Boomerang.


1
Saya pikir Anda bisa mendapatkan satu byte lagi dengan pindah 2*mod i 2ke lkemudian Anda dapat menghapus tanda kurung. Seperti ini: l a=2*mod a 2:scanl(+)1(l a)danf n=[l i!!i|i<-[0..n]]
basile-henry

@Boomerang Yup, itu berhasil. Terima kasih
Michael Klein

5

ES6, 65 byte

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

Menggunakan relasi perulangan yang diberikan dalam pertanyaan.


5

Retina , 70 62 59 byte

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

f
1

Cobalah online

  • Input dalam basis unary, n 1s.
  • 1? $`¶- Buat garis untuk setiap angka dari 0 hingga n : , 1, 11, 111, 1111, ...
  • m`^(11)*1$ $&ff- Tambahkan ffgaris ganjil. Ini akan menaburkan fungsi dengan L (0) = 2.
  • m`$  f- Tambahkan  fke semua baris (perhatikan spasi). Ini menaburkan fungsi dengan 0 dan 1 untuk angka Fibonacci, dan 2 dan 1 untuk angka Lucas.
  • +`1(f*) (f*) $2 $2$1 - Loop: menghitung F (n + 1) = F (n) + F (n-1) saat masih ada 1s.
  •  f*   - Hapus F (n +1) dari ujung setiap baris.
  • Ganti fkembali ke 1s. Jika ini tidak diperlukan dan kita bisa tetap dengan fs, panjangnya hanya 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;

Tidak bermain golf

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;

Saya berhasil mendapatkan beberapa byte dengan menggunakan (menyalahgunakan?) Fungsi SIGN untuk menghasilkan 3 elemen pertama dari urutan.


3

Japt, 25 22 21 byte

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

Uji secara online!

Latar Belakang

Agak sulit untuk membuat urutan Fibonacci di Japt, tetapi kami memiliki bawaan Mguntuk melakukannya untuk kami. Namun, ini hanya memberi kita urutan Fibonacci, bukan urutan Lucas. Kita dapat menyelesaikan urutan Lucas dengan cukup mudah menggunakan trik ini:

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

Seperti yang Anda lihat, F(N-1) + F(N+1)sama L(N)untuk semua N. Namun, karena kita hanya membutuhkan angka Lucas pada indeks ganjil, kita dapat menggabungkan dua rumus menjadi satu:

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

Bagaimana itu bekerja

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~#&

Ide yang sangat mirip dengan Martin di atas, saya meluangkan waktu mencoba mencari cara yang lebih pendek untuk mendefinisikan "kasus dasar" untuk fungsi. Interpolasi polinomial adalah sebuah kegagalan, jadi saya menggunakan ini, menggunakan ekstensi menjadi negatif untuk menghasilkan definisi yang cukup singkat.


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~#&

Implementasi yang sangat mudah. Menentukan fungsi helper fdan kemudian mengevaluasi ke fungsi yang tidak disebutkan namanya yang berlaku funtuk rentang untuk mendapatkan semua hasil. Ini terasa tidak perlu rumit.

Fungsi tunggal yang tidak disebutkan namanya tampaknya satu byte lebih lama:

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

Terjemahan hampir langsung dari jawaban Martin CJam .

Cobalah 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\

Ini mengambil nomor sebagai input dan mencetak untuk STDOUT daftar, dengan spasi memisahkan setiap nomor.

Penjelasan

§ 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

Pemotongan !dalam aturan pertama dari sub-predikat 1 diperlukan sehingga ketika kita mundur ( \), kita tidak berakhir dalam loop tak terbatas di mana penerjemah akan mencoba aturan kedua untuk input yang kurang dari 4.



2

Groovy, 50 Bytes

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

Ini mendefinisikan fungsi x, yang mengambil n sebagai argumen pertama dan memiliki kasus dasar dari empat angka pertama dalam urutan Fibocas sebagai argumen default untuk sisa fungsi.

a di sini adalah n. b, c, d, dan e adalah empat elemen berikutnya dalam urutan.

Ini mengurangi n dan berulang sampai n kurang dari nol - ketika berulang, itu menambah nilai pengembalian akhir elemen pertama dalam urutan saat ini. Nilai baru untuk empat elemen berikutnya dalam urutan diberikan ke panggilan rekursif - tiga elemen terakhir digeser menjadi tiga yang pertama, dan elemen keempat yang baru dihasilkan dari dua elemen sebelumnya menggunakan 3 * db.

Ini membatasi nilai-nilai baru dengan daftar sarang, karena asyik dapat mengembalikan beberapa nilai dengan memasukkannya ke dalam daftar - sehingga setiap panggilan mengembalikan elemen pertama saat ini dan hasil rekursi, yang akan menjadi daftar sendiri.



1

Pylons , 19

Ini adalah terjemahan langsung dari pendekatan Martin.

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

Bagaimana itu bekerja:

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!

Lambda anonim yang meninggalkan urutan angka di tumpukan. Pemakaian:

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

Penjelasan

[                              {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)

Ini sepertinya terlalu lama. Namun, saya senang bisa menggunakan notoperator bitwise ... dua kali. Sekali sebagai semacam paritas bolak-balik, dan sekali untuk mengakhiri rekursi ketika nmencapai -1.

Variabel pakan selalu berupa 0atau -1, sehingga akan bergantian antara entri 0atau -1daftar. (Memilih entri -1daftar Python berarti memilih elemen terakhir.)


1

C ++ Template Meta Programming, 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)

Definisi rekursif, entah bagaimana, menangis untuk C ++ TMP, penggunaan:

L<x>::v

dengan xmenjadi yang A(x)kamu suka.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.