ตัวเลข Lucas-nacci


19

พื้นหลัง

ทุกคนส่วนใหญ่คุ้นเคยกับตัวเลขฟีโบนักชี F(n) :

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

เหล่านี้จะเกิดขึ้นจากฟังก์ชั่นเรียกซ้ำตัวเองF(n) = F(n-1) + F(n-2)ด้วยและF(0)=0 A000045F(1)=1

ลำดับที่เกี่ยวข้องอย่างใกล้ชิดคือหมายเลข Lucas L(m) :

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

เหล่านี้จะเกิดขึ้นจากฟังก์ชั่นเรียกซ้ำตัวเองL(m) = L(m-1) + L(m-2)ด้วยและL(0)=2 A000032L(1)=1

เราสามารถสลับระหว่างสองลำดับขึ้นอยู่กับดัชนีคู่ / คี่กับการก่อสร้าง
A(x) = F(x)ถ้าx mod 2 = 0และเป็นA(x) = L(x)อย่างอื่น ตัวอย่างเช่นA(4)มีค่าเท่ากับตั้งแต่F(4) 4 mod 2 = 0เราจะเรียกลำดับนี้เบอร์ Lucas-nacci , A(x):

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

นี้สามารถเกิดขึ้นจากฟังก์ชั่นเรียกซ้ำตัวเองA(x) = 3*A(x-2) - A(x-4)ด้วยA(0)=0, A(1)=1, และA(2)=1 A005013A(3)=4

ท้าทาย

รับอินพุตnส่งออกลำดับของn+1ตัวเลขถึงและรวมถึงA(n)ตามที่อธิบายไว้ข้างต้น ไบต์น้อยที่สุด (หรือไบต์เทียบเท่าเช่นLabVIEWตามที่กำหนดเป็นรายบุคคลใน Meta) ชนะ

อินพุต

nจำนวนเต็มไม่เป็นลบเดียว

เอาท์พุต

รายการของตัวเลขที่สอดคล้องกับ subsequence ของตัวเลข Lucas-nacci จากไปA(0) A(n)รายการจะต้องอยู่ในลำดับตามที่อธิบายไว้ข้างต้น

กฎระเบียบ

  • กฎของรหัสกอล์ฟมาตรฐานและข้อ จำกัด ทางหนีใช้
  • ใช้กฎอินพุต / เอาต์พุตมาตรฐาน
  • หมายเลขอินพุตสามารถอยู่ในรูปแบบที่เหมาะสม: unary หรือทศนิยมอ่านจาก STDIN ฟังก์ชันหรืออาร์กิวเมนต์บรรทัดคำสั่ง ฯลฯ - ตัวเลือกของคุณ
  • เอาต์พุตสามารถพิมพ์ไปที่ STDOUT หรือส่งคืนเป็นผลมาจากการเรียกใช้ฟังก์ชัน หากพิมพ์ตัวคั่นที่เหมาะสมเพื่อแยกความแตกต่างจะต้องรวมอยู่ด้วย (คั่นด้วยช่องว่างคั่นด้วยเครื่องหมายจุลภาค ฯลฯ )
  • นอกจากนี้หากเอาต์พุตไปยัง STDOUT, ช่องว่างโดยรอบ, การขึ้นบรรทัดใหม่, ฯลฯ จะเป็นตัวเลือกทั้งหมด
  • หากอินพุตเป็นจำนวนเต็มที่ไม่ใช่หรือจำนวนเต็มลบโปรแกรมสามารถทำอะไรก็ได้หรืออะไรก็ได้เนื่องจากพฤติกรรมไม่ได้กำหนดไว้

ตัวอย่าง

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

ขึ้นบรรทัดใหม่ถือเป็นตัวคั่นที่ยอมรับหรือไม่
corsiKa

@corsiKa แน่นอนว่าไม่เป็นไร
AdmBorkBork

คำตอบ:


9

เยลลี่ 12 ไบต์

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

ลองออนไลน์!

พื้นหลัง

เราสามารถขยาย F และ L เป็น -1 ได้โดยกำหนด F (-1) = 1 และ L (-1) = -1 สิ่งนี้สอดคล้องกับฟังก์ชั่นวนซ้ำ

โปรแกรมของเราเริ่มต้นด้วย

-1  1
 0  2

ในแต่ละขั้นตอนเพื่อสร้างคู่ต่อไปเรากลับคู่สุดท้ายและเพิ่มไปยังคู่สุดท้าย ตัวอย่างเช่น:

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

หากเราทำกระบวนการนี้ต่อไปอีกไม่กี่ขั้นตอนเราก็จะได้

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

ลำดับ Lucas-nacci เป็นเพียงคอลัมน์ด้านซ้าย

มันทำงานอย่างไร

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

С peeks ที่สองเชื่อมโยงไปยังด้านซ้าย: และ2 U+¥เนื่องจากซ้ายสุดเป็น nilad จึงไม่สามารถเป็นเนื้อความของวนซ้ำได้ ดังนั้น,U+¥ใช้เป็น body และอ่านตัวเลขจากอินพุต เนื่องจากไม่มีอาร์กิวเมนต์บรรทัดคำสั่งหมายเลขนั้นจึงถูกอ่านจาก STDIN


2
ฉันได้รับความประทับใจว่าคุณทำสิ่งนี้ (เล่นกอล์ฟในเยลลี่) เพื่อหาเลี้ยงชีพ ซึ่งทำให้ฉันกลัว
Draco18s

24
ถ้าใครเรียงลำดับวิธีการเล่นกอล์ฟ (รหัส) สำหรับชีวิตโปรด ping ฉันในการแชท ถามเพื่อน ...
Martin Ender

2
โดยพื้นฐานแล้วคุณเพียงแค่คำนวณลำดับทั้งสอง แต่กลับในแต่ละขั้นตอนซึ่งสลับระหว่างลำดับได้อย่างมีประสิทธิภาพ
Neil

1
@ Neil ใช่แน่นอน มันหลีกเลี่ยงการสอดแทรกลำดับหลังจากนั้นซึ่งจะนานกว่าเล็กน้อย
เดนนิส

6

CJam, 21 20 ไบต์

ขอบคุณ Sp3000 สำหรับการบันทึก 1 ไบต์

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

ทดสอบที่นี่

คำอธิบาย

เพียงแค่ใช้การเกิดซ้ำที่ให้ไว้ในข้อมูลจำเพาะของการท้าทาย

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
ใครคือ Sp3000 ที่คุณขอบคุณทุกคำตอบ
CJ Dennis


5
@CDDennis บางคนบอกว่าเขาเป็นนักกอล์ฟ Python ที่ยิ่งใหญ่ที่สุดที่เคยมีชีวิตอยู่ บางคนบอกว่าเขาอาศัยอยู่ในกระท่อมที่เงียบสงบบนยอดเขาซึ่งสร้างจากท่อนซุงจำนวนน้อยที่สุด บางคนบอกว่าเขาเป็นเสียงที่อยู่ด้านหลังหัวของเราซึ่งทำให้เราไม่รู้สึกเมื่อเราโพสต์วิธีแก้ไขปัญหาซึ่งสามารถตีกอล์ฟต่อไปได้ แต่พวกเราส่วนใหญ่บอกว่าเขาเป็นผู้ใช้ที่มาร์ตินเชื่อมโยงกับโปรไฟล์
Mego

6

Perl 6, 42 ไบต์

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

การใช้

> 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
แลมบ์ดาที่ชัดเจนที่สุดที่ฉันคิดไว้คือ{( (0,1,*+*...*) Z (2,1,*+*...*) ).flat.rotor( 1=>2, 1=>0 )[ 0..$_ ].flat}
แบรดกิลเบิร์ต b2gills

ระบุว่าการใช้ถ้อยคำที่แน่นอน "ให้ n", (0,1,1,4,{$^b;$^d;3*$^c-$^a}...*)[^(n+1)]คุณสามารถประหยัดไบต์ด้วย:
raiph

6

Haskell, 59 , 57 , 56 , 52 , 51 ไบต์

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

คำนิยามชุดดัดแปลงมาจากคำตอบนี้นี้

หักกอล์ฟ:

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 startให้รายการอนันต์ที่กำหนดไว้: f(0)=start, f(1)=1, f(n)=f(n-1) + f(n-2). whichStart iส่งคืน 2 สำหรับคี่อินพุต (ชุด Lucas) หรือ 0 สำหรับคู่ (ชุด Fibonacci) lucasNacci iให้หมายเลข ith Lucas-nacci firstN nแผนที่เหนือรายการ

หนึ่งไบต์บันทึกโดย Boomerang


1
ฉันคิดว่าคุณจะได้รับอีกหนึ่งไบต์โดยย้าย2*mod i 2เข้าไปlแล้วคุณสามารถลบวงเล็บ เช่นนี้: l a=2*mod a 2:scanl(+)1(l a)และf n=[l i!!i|i<-[0..n]]
basile-henry

@Boomerang Yup นั่นใช้งานได้ ขอบคุณ
Michael Klein

5

ES6, 65 ไบต์

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

ใช้ความสัมพันธ์ที่เกิดซ้ำในคำถาม


5

Retina , 70 62 59 ไบต์

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

f
1

ลองออนไลน์

  • อินพุตอยู่ในฐานเดียว, n 1s
  • 1? $`¶- สร้างบรรทัดสำหรับแต่ละหมายเลขตั้งแต่ 0 ถึงn : , 1, 11, 111, 1111, ...
  • m`^(11)*1$ $&ff- ต่อท้ายffบรรทัดคี่ สิ่งนี้จะทำให้ฟังก์ชันมีค่า L (0) = 2
  • m`$  f- ต่อท้าย fทุกบรรทัด (จดบันทึกช่องว่าง) ฟังก์ชันนี้ใช้ฟังก์ชันด้วย 0 และ 1 สำหรับหมายเลขฟีโบนักชีและ 2 และ 1 สำหรับหมายเลขลูคัส
  • +`1(f*) (f*) $2 $2$1 - ลูป: คำนวณ F (n + 1) = F (n) + F (n-1) ในขณะที่ยังมี 1 วินาที
  •  f*   - ลบ F (n + 1) จากส่วนท้ายของแต่ละบรรทัด
  • แทนที่fs กลับเป็น 1 วินาที หากไม่ต้องการและเราสามารถอยู่กับfs ความยาวเพียง 55 ไบต์

5

Oracle SQL 11.2 218 216 201 ไบต์

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;

ยกเลิกแข็งแรงเล่นกอล์ฟ

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;

ฉันจัดการเพื่อให้ได้สองสามไบต์โดยใช้ (ใช้ผิดวิธี) ฟังก์ชัน SIGN เพื่อสร้างองค์ประกอบ 3 ลำดับแรก


3

Japt, 25 22 21 ไบต์

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

ทดสอบออนไลน์!

พื้นหลัง

มันค่อนข้างยากที่จะสร้างลำดับฟีโบนักชีใน Japt แต่เรามีบิวด์อินที่Mgจะทำเพื่อเรา อย่างไรก็ตามนี่ให้ลำดับ Fibonacci เท่านั้นไม่ใช่ลำดับ Lucas เราสามารถทำตามลำดับลูคัสได้อย่างง่ายดายโดยใช้เคล็ดลับนี้:

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

ในขณะที่คุณสามารถดูF(N-1) + F(N+1)มีค่าเท่ากับทั้งหมดL(N) Nอย่างไรก็ตามเนื่องจากเราต้องการเพียงตัวเลข Lucas ในดัชนีคี่เราจึงสามารถรวมสูตรทั้งสองเข้าเป็นหนึ่งเดียว:

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

มันทำงานอย่างไร

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 ไบต์

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

แนวคิดที่คล้ายกันมากกับของมาร์ตินฉันใช้เวลาพยายามหาวิธีที่สั้นกว่าในการนิยาม "เคสพื้นฐาน" สำหรับฟังก์ชั่น การแก้ไขพหุนามเป็นรูปปั้นครึ่งตัวดังนั้นฉันจึงไปหาสิ่งนี้โดยใช้ส่วนขยายในเชิงลบเพื่อให้ได้คำจำกัดความที่ค่อนข้างสั้น


2

Mathematica, 56 ไบต์

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

การติดตั้งใช้งานง่ายมาก กำหนดฟังก์ชั่นตัวช่วยfแล้วประเมินฟังก์ชันที่ไม่มีชื่อซึ่งใช้fกับช่วงเพื่อให้ได้ผลลัพธ์ทั้งหมด สิ่งนี้ทำให้รู้สึกยุ่งยากโดยไม่จำเป็น

ฟังก์ชั่นที่ไม่มีชื่อเดียวดูเหมือนว่าจะมีความยาวหนึ่งไบต์ แต่:

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

2

MATL , 17 18ไบต์

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

แปลเกือบโดยตรงของมาร์ตินคำตอบ CJam

ลองออนไลน์!

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 ไบต์

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

ใช้ตัวเลขเป็นอินพุตและพิมพ์ไปยัง STDOUT รายการโดยมีช่องว่างคั่นแต่ละหมายเลข

คำอธิบาย

§ 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

การตัด!ในกฏแรกของ sub-predicate 1 เป็นสิ่งจำเป็นดังนั้นเมื่อเราย้อนกลับ ( \) เราจะไม่สิ้นสุดในลูปที่ไม่มีที่สิ้นสุดที่ล่ามจะลองกฎที่สองสำหรับอินพุตที่น้อยกว่า 4



2

Groovy ขนาด 50 ไบต์

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

ฟังก์ชันนี้กำหนดฟังก์ชัน x ซึ่งรับ n เป็นอาร์กิวเมนต์แรกและมีตัวพิมพ์ใหญ่ของตัวเลขสี่ตัวแรกในลำดับ Fibocas เป็นอาร์กิวเมนต์เริ่มต้นสำหรับส่วนที่เหลือของฟังก์ชัน

ที่นี่คือ n b, c, d และ e เป็นองค์ประกอบสี่ลำดับถัดไปในลำดับ

มันจะลด n และเกิดซ้ำจนกว่า n จะน้อยกว่าศูนย์ - เมื่อมันเกิดขึ้นอีกมันจะเพิ่มไปยังค่าตอบแทนสุดท้ายขององค์ประกอบแรกในลำดับปัจจุบัน ค่าใหม่สำหรับองค์ประกอบสี่ลำดับถัดไปจะถูกกำหนดให้กับการเรียกแบบเรียกซ้ำ - องค์ประกอบทั้งสามจะถูกเลื่อนไปเป็นสามอันดับแรกและองค์ประกอบที่สี่ใหม่จะถูกสร้างขึ้นจากสององค์ประกอบก่อนหน้านี้โดยใช้ 3 * db

มันคั่นค่าใหม่ด้วย list nestings เนื่องจาก groovy สามารถคืนค่าหลายค่าโดยการใส่ลงในรายการ - ดังนั้นการโทรแต่ละครั้งจะส่งคืนองค์ประกอบแรกปัจจุบันและผลลัพธ์ของการเรียกซ้ำซึ่งจะเป็นรายการของตัวเอง



1

เสาใหญ่อายุ 19 ปี

นี่คือการแปลโดยตรงจากแนวทางของ Martin

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

มันทำงานอย่างไร:

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 ไบต์

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

Try it here!

แลมบ์ดานิรนามที่ทิ้งหมายเลขไว้บนสแต็ก การใช้งาน:

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

คำอธิบาย

[                              {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 ไบต์

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)

ดูเหมือนจะยาวเกินไป อย่างไรก็ตามฉันดีใจที่ฉันได้ใช้ตัวnotดำเนินการระดับบิต... สองครั้ง เมื่อเป็นชนิดของความเท่าเทียมกันกลับพลิกมาและครั้งเดียวที่จะยุติการเรียกซ้ำเมื่อต้นน้ำn-1

ตัวแปรpจะเป็นอย่างใดอย่างหนึ่ง0หรือ-1ดังนั้นจึงจะสลับระหว่างรายการ0หรือ-1ของรายการ (การเลือกรายการ-1ของรายการPython หมายถึงการเลือกองค์ประกอบสุดท้าย)


1

เทมเพลตการเขียนโปรแกรม C ++ เทมเพลตขนาด 130 ไบต์

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)

คำจำกัดความซ้ำแบบใดก็ตามที่ร้องไห้สำหรับ C ++ TMP การใช้งาน:

L<x>::v

ด้วยxการเป็นคนที่A(x)คุณชอบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.