กำลังคำนวณ (3 + sqrt (5)) ^ n อย่างแน่นอน


23

วันนี้เป้าหมายของคุณคือการหาจำนวนเต็มและbให้จำนวนเต็มไม่เป็นลบnดังกล่าวว่า:

(3 + sqrt (5)) ^ n = a + b * sqrt (5)

คุณควรเขียนโปรแกรมหรือฟังก์ชั่นที่รับพารามิเตอร์nและเอาท์พุตaและbในรูปแบบที่คุณเลือก

ช่องโหว่มาตรฐานใช้ นอกจากนี้ยังมีวัตถุประสงค์เพื่อให้คุณใช้ปัญหาข้างต้นโดยใช้เลขคณิตพื้นฐานด้วยตัวคุณเอง ดังนั้นคุณไม่สามารถใช้ฟังก์ชันพีชคณิต, ปันส่วนหรือฟังก์ชันที่ใช้โครงสร้างทางคณิตศาสตร์ที่ไม่สำคัญ (ตัวอย่างเช่นลำดับลูคัส )

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


ตัวอย่างอินพุต / เอาต์พุต:

0 → 1, 0
1 → 3, 1
2 → 14, 6
3 → 72, 32
4 → 376, 168
5 → 1968, 880
6 → 10304, 4608
7 → 53952, 24128
8 → 282496, 126336
9 → 1479168, 661504

คำตอบ:


3

Dyalog APL ขนาด 18 ไบต์

((3∘×+5 1×⌽)⍣⎕)1 0

นี้เป็นโปรแกรมที่จะเข้าผ่าน

 (         )         Monadic train:
  3∘×                3 times argument
     +               Plus
      5 1×⌽          (5 1) times the reverse
(           ⍣⎕)      Apply that function (input) times
               1 0   starting with (1 0)

คุณลักษณะที่ใช้ในที่นี้ถูกนำมาใช้อย่างดีก่อนเดือนเมษายน 2015 ทำให้คำตอบนี้ใช้ได้

ลองมันนี่ โปรดทราบว่า tryapl.org เป็นชุดย่อย จำกัด ของ Dyalog และไม่สนับสนุนการ


16

อ็อกเทฟ 26 ไบต์

[3 5;1 3]**input('')*[1;0]

เพราะ ( a + b * sqrt (5)) * (3 + sqrt (5)) = ( 3a + 5b ) + ( a + 3b ) * sqrt (5)

เวกเตอร์ใส่ทวีคูณ

| 1 |    /* a = 1 */
| 0 |    /* b = 0 */

ซึ่งหมายถึง 1 = (3 + sqrt (5)) ^ 0 โดยเมทริกซ์

| 3 5 |
| 1 3 |

ดูเหมือนเป็นธรรมชาติ แทนที่จะวนลูปnครั้งเราค่อนข้างยกเมทริกซ์ให้เป็นกำลังnแล้วคูณมันด้วยเวกเตอร์อินพุต


คุณกำลังขายตัวเองสั้น ๆ[3 5;1 3]**input('')*[1;0]คือ 26 ไบต์ไม่ใช่ 41
หรือ

3
@(n)[3 5;1 3]^n*[1;0](ที่จับฟังก์ชั่น) จะช่วยให้คุณประหยัดห้าตัวละครปิดบังความคิดที่ดี!
ข้อบกพร่อง

14

Python 2, 50

a=1;b=0
exec"a,b=3*a+5*b,3*b+a;"*input()
print a,b

คูณ3+sqrt(5)ซ้ำแล้วซ้ำอีกโดยการกระทำในวันที่ทั้งคู่เป็นตัวแทน(a,b) a+b*sqrt(5)เทียบเท่ากับการเริ่มต้นด้วยเวกเตอร์คอลัมน์[1,0]และซ้ายคูณครั้งโดยเมทริกซ์n[[3,5],[1,3]]


12

Julia, 22 20 ไบต์

n->[3 5;1 3]^n*[1;0]

สิ่งนี้จะสร้างฟังก์ชั่นแลมบ์ดาซึ่งรับค่าจำนวนเต็มเดียวเป็นอินพุตและส่งกลับเวกเตอร์ 2 องค์ประกอบของจำนวนเต็มที่สอดคล้องกับโซลูชัน [a, b] f=n->...เรียกว่าให้มันชื่อเช่น

เริ่มต้นด้วยการคูณ

Initial expand

จากนั้นเราสามารถแปลทางด้านขวาของสมการนี้เป็นเมทริกซ์ 2 คอลัมน์โดยที่แรกตรงกับสัมประสิทธิ์ของaและที่สองเป็นสัมประสิทธิ์ของb :

Matrix

คูณเมทริกซ์นี้ด้วยตัวเอง nคูณจากนั้นคูณด้วยเวกเตอร์คอลัมน์ (1, 0) และ POOF! Out pops เวกเตอร์โซลูชัน

ตัวอย่าง:

julia> println(f(0))
[1,0]

julia> println(f(5))
[1968,880]

8

J, 20 ไบต์

+/@:*(3 5,.1 3&)&1 0

คูณเวกเตอร์[1 0]ด้วยเมทริกซ์[[3 5] [1 3]] nครั้ง

บันทึก 2 ไบต์ด้วย @algorithmshark

การใช้งานและทดสอบ:

   (+/@:*(3 5,.1 3&)&1 0) 5
1968 880

   (+/@:*(3 5,.1 3&)&1 0) every i.6
   1   0
   3   1
  14   6
  72  32
 376 168
1968 880

คุณจะได้รับลงไปที่ 20 +/ .*(3 5,:1 3&)&1 0โดยการใช้ประโยชน์จากการแยกคำวิเศษณ์โดยปริยาย:
algorithmshark

@algorithmshark ขอบคุณแม้ว่าทำไมถึงใช้(+/@:*&(3 5,.1 3)&1 0)งาน(+/@:*&1 0&(3 5,.1 3))ได้และไม่ใช่ ไม่ควรพันธบัตรอันที่สองถูกต้องและอันแรกเปลี่ยนได้หรือไม่
randomra

เข้าใจแล้วพวกมันจะผูกมัดอย่างที่ฉันคาดไว้ แต่ด้านนอก&ทำให้การเปิด / ปิดเพื่อให้คุณปรับเปลี่ยนอินพุตด้านซ้ายในระหว่างการเปิดเครื่อง (ตรงข้ามกับการดัดแปลงด้านขวาปกติ)
randomra

7

Pyth, 20 ไบต์

u,+*3sGyeG+sGyeGQ,1Z

uซึ่งลดลงโดยทั่วไปจะใช้ที่นี่เป็นลูปนำไปใช้ซ้ำ ฟังก์ชั่นการอัพเดทคือG-> ,+*3sGyeG+sGyeGโดยที่G2 tuple 3*sum(G) + 2*G[1], sum(G) + 2*G[1]ฟังก์ชั่นที่แปลว่า sเป็นsum, เป็นy*2


ฉันเลือก @ randomra คำตอบของคุณมากกว่าเพราะ / เขาของเขาถูกโพสต์เมื่อ 16 นาทีก่อนขออภัยด้วย
orlp

5

APL (22)

{⍵+.×⍨2 2⍴3 5 1}⍣⎕⍨2↑1

คำอธิบาย:

  • {... }⍣⎕⍨2↑1: อ่านตัวเลขแล้วเรียกใช้ฟังก์ชันต่อไปนี้หลายครั้งโดยใช้[1,0]เป็นอินพุตเริ่มต้น
    • 2 2⍴3 5 1: เมทริกซ์ [[3,5],[1,3]]
    • ⍵+.×⍨: คูณจำนวนแรกด้วย⍵ด้วย 3, สองด้วย 5 แล้วหาผลรวม, นี่คือตัวเลขแรกใหม่; จากนั้นคูณจำนวนแรกด้วย⍵ด้วย 1, ที่สองคูณ 3 แล้วหาผลรวมนั่นคือตัวเลขที่สองใหม่

1
Awww yiss, APL
นิด

5

เยลลี่ขนาด 13 ไบต์

5W×U++Ḥ
2Bdz¡

ลองออนไลน์!

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

5W×U++Ḥ    Helper link. Argument: [a, b]

5W         Yield [5].
  ×U       Multiply it by the reverse of [a, b]. This yields [5b, a].
    +      Hook; add the argument to the result. This yields [a + 5b, a + b].
     +Ḥ    Fork; add the doubled argument ([2a, 2b]) to the result.
           This yields [3a + 5b, a + 3b].

2Bdz¡      Main link. Argument: n

2B         Convert 2 to binary, yielding [1, 0].
    ¡      Repeat:
  Ç            Apply the helper link...
   ³           n times.

ไม่ฉันค่อนข้างมั่นใจว่าเจลลี่อยู่ในช่วงเวลานานก่อนที่จะมีการสร้างอินเทอร์เน็ต: P
Conor O'Brien

1
@ Doᴡɴɢᴏᴀᴛสำหรับคำตอบที่ไม่ใช่การแข่งขันฉันต้องการให้นับไบต์ในบรรทัดที่สอง สิ่งนี้จะช่วยป้องกันคำตอบจากการเพิ่มขึ้นเป็นผู้นำในกระดานผู้นำและผู้ใช้สคริปต์ซึ่งดูเหมือนว่าไม่ยุติธรรม
เดนนิส


3

CJam, 21 ไบต์

0X{_2$3*+@5*@3*+}li*p

ลองออนไลน์

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

0X       " Stack: [ 0 1 ]                                ";
li{      " Do int(input()) times:                        ";
  _2$    " Stack: [ a b ] -> [ a b b a ]                 ";
  3*+    " Stack: [ a b b a ] -> [ a b (b+3a) ]          ";
  @5*@3* " Stack: [ a b (b+3a) ] -> [ (b+3a) 5a 3b ]     ";
  +      " Stack: [ (b+3a) 5a 3b ] -> [ (b+3a) (5a+3b) ] ";
}*       "                                               ";
p        " Print topmost stack item plus linefeed.       ";
         " Print remaining stack item (implicit).        ";

3

Javascript, 63 61 ไบต์

ฉันกำลังใช้การประเมินแบบเรียกซ้ำของทวินาม: (x + y) ^ n = (x + y) (x + y) ^ {n-1}

ใหม่ (ขอบคุณ @ edc65)

F=n=>{for(i=y=0,x=1;i++<n;)[x,y]=[3*x+5*y,x+3*y];return[x,y]}

เก่า

F=n=>{for(i=y=0,x=1;i<n;i++)[x,y]=[3*x+5*y,x+3*y];return [x,y]}

1
อาจต้องการพิจารณาแก้ไขสูตรของคุณ เราไม่มี MathJax อีกต่อไป
Alex A.

ฉันคิดว่ามันเพิ่งเปิดตัวเมื่อไม่กี่วันที่ผ่านมา?
ข้อบกพร่อง

ใช่ แต่มันทำให้ตัวอย่างสแต็กสับสนดังนั้นจึงต้องปิดการใช้งาน
Alex A.

ฉันนับ 63 ตามที่เป็นอยู่และสามารถย่อให้เหลือ 61F=n=>{for(i=y=0,x=1;i++<n;)[x,y]=[3*x+5*y,x+3*y];return[x,y]}
edc65

n=>[...Array(n)].map(_=>[x,y]=[3*x+5*y,x+3*y],y=0,x=1)[n-1]ความยาวเท่ากัน
l4m2

2

C, 114 ไบต์

g(n){int i,a[2]={1,0},b[2];for(i=0;i<n;i++)*b=*a*3+5*a[1],b[1]=*a+3*b[1],*a=*b,a[1]=b[1];printf("%d,%d",*a,a[1]);}

การดำเนินการคูณเมทริกซ์นี้เป็นวิธีที่น่าเบื่อ เพื่อความสนุกสนานมากขึ้น (อ้างถึง: "สุดยอดน่ากลัว") วิธีแก้ปัญหา 238 ไบต์ไม่ต้องมองหาที่ไหนอีกแล้ว!

f(n){int p[2][n+3],i,j,k=0,a[2]={0};for(j=0;j<n+3;j++)p[0][j]=0;*p[1]=0;(*p)[1]=1;for(j=0;j<n;j++,k=!k)for(i=1;i<n+3;i++)p[!k][i]=p[k][i-1]+p[k][i];for(i=1;i<n+2;i++)a[!(i%2)]+=p[k][i]*pow(3,n+1-i)*pow(5,(i-1)/2);printf("%d,%d",*a,a[1]);}

หลุด:

g(n){
    int i,a[2]={1,0},b[2];
    for(i=0;i<n;i++)
        *b=3**a+5*a[1],b[1]=*a+3*b[1],*a=*b,a[1]=b[1];
    printf("%d,%d",*a,a[1]);
}

อาจจะสั้นลงเล็กน้อย ลองใช้โปรแกรมทดสอบออนไลน์ !


1
นี่ใช้อัลกอริธึมที่ค่อนข้างซับซ้อน: P
orlp

@ หรือฉันไม่สามารถคิดอัลกอริทึมที่สั้นกว่าสำหรับภาษานี้ ฉันคิดว่าอันนี้จะได้ผล แต่มันก็ออกไปจากมือฮ่าฮ่า การใช้การคูณเมทริกซ์ด้วยมืออาจสั้นกว่ามาก
BrainSteel

1
โหวตขึ้นเพราะนี่มันสุดยอดมาก
kirbyfan64sos

2

k2 - 22 ตัวอักษร

ฟังก์ชั่นรับหนึ่งอาร์กิวเมนต์

_mul[(3 5;1 3)]/[;1 0]

_mulเป็นคูณเมทริกซ์เพื่อให้เราแกงกับเมทริกซ์(3 5;1 3)แล้วตีมันด้วยคำวิเศษณ์อำนาจการทำงาน: f/[n;x]ใช้fเพื่อx, nครั้ง คราวนี้เราเริ่มด้วยเวกเตอร์1 0อีกครั้ง

  _mul[2 2#3 5 1]/[;1 0] 5
1968 880
  f:_mul[2 2#3 5 1]/[;1 0]
  f'!8  /each result from 0 to 7 inclusive
(1 0
 3 1
 14 6
 72 32
 376 168
 1968 880
 10304 4608
 53952 24128)

สิ่งนี้จะไม่ทำงานใน Kona เพราะด้วยเหตุผลบางอย่างf/[n;x]ไม่สามารถใช้งานได้อย่างถูกต้อง เฉพาะn f/xไวยากรณ์ที่ใช้งานได้ดังนั้นการแก้ไขที่สั้นที่สุดคือ{x _mul[(3 5;1 3)]/1 0}23 ถ่าน


ว้าว. การใช้การแกงอย่างฉลาดฉันรู้สึกว่าคำตอบ K ของฉันนั้นโง่ อย่างไรก็ตามผมยกประเด็นที่คุณพบใน Kona บนของพวกเขาติดตามข้อผิดพลาด
kirbyfan64sos


2

ised, 25 ไบต์ (20 ตัวอักษร)

({:{2,4}·x±Σx:}$1)∘1

ฉันหวังว่าจะดีขึ้น แต่มีการจัดฟันที่จำเป็นมากเกินไปในการที่จะทำให้มันมีความสามารถ

โดยคาดว่าอินพุตจะอยู่ในสล็อตหน่วยความจำ $ 1 ดังนั้นจึงสามารถใช้งานได้:

ised '@1{9};' '({:{2,4}·x±Σx:}$1)∘1'

สำหรับ n = 0 ศูนย์จะถูกข้าม (เอาท์พุท 1 แทน 1 0) หากเป็นปัญหาแทนที่สุดท้ายกับ1~[2]


2

อย่างจริงจัง 32 ไบต์ไม่ใช่การแข่งขัน

,╗43/12`╜";)@4*≈(6*-"£n.X4ì±0`n

ฐานสิบหก:

2cbb34332f313260bd223b2940342af728362a2d229c6e2e58348df130606e7f

ลองใช้ Onlline

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

a_n = 6 * a_ {n-1} - 4 * a_ {n-2})


1

Haskell, 41 ไบต์

(iterate(\(a,b)->(3*a+5*b,a+3*b))(1,0)!!)

ตัวอย่างการใช้งาน: ->(iterate(\(a,b)->(3*a+5*b,a+3*b))(1,0)!!) 8(282496,126336)


1

C / C ++ 89 ไบต์

void g(int n,long&a,long&b){if(n){long j,k;g(n-1,j,k);a=3*j+5*k;b=j+3*k;}else{a=1;b=0;}}

จัดรูปแบบ:

    void g(int n, long&a, long&b) {
if (n) {
    long j, k;
    g(n - 1, j, k);
    a = 3 * j + 5 * k;
    b = j + 3 * k;
} else {
    a = 1;
    b = 0;
}}

แนวคิดเดียวกัน:

void get(int n, long &a, long& b) {
    if (n == 0) {
        a = 1;
        b = 0;
        return;
    }
    long j, k;
    get(n - 1, j, k);
    a = 3 * j + 5 * k;
    b = j + 3 * k;
}

ม้านั่งทดสอบ:

#include <iostream>
using namespace std;    
int main() {
    long a, b;
    for (int i = 0; i < 55; i++) {
        g(i, a, b);
        cout << i << "-> " << a << ' ' << b << endl;
    }
    return 0;
}

ผลลัพธ์:

0-> 1 0
1-> 3 1
2-> 14 6
3-> 72 32
4-> 376 168
5-> 1968 880
6-> 10304 4608
7-> 53952 24128
8-> 282496 126336
9-> 1479168 661504
10-> 7745024 3463680
11-> 40553472 18136064
12-> 212340736 94961664
13-> 1111830528 497225728
14-> 5821620224 2603507712
15-> 30482399232 13632143360
16-> 159607914496 71378829312
17-> 835717890048 373744402432
18-> 4375875682304 1956951097344
19-> 22912382533632 10246728974336
20-> 119970792472576 53652569456640
21-> 628175224700928 280928500842496
22-> 3289168178315264 1470960727228416
23-> 17222308171087872 7702050360000512
24-> 90177176313266176 40328459251089408
25-> 472173825195245568 211162554066534400
26-> 2472334245918408704 1105661487394848768

ยินดีต้อนรับสู่เว็บไซต์และคำตอบแรกที่ดี!
DJMcMayhem

0

K, 37 ไบต์

f:{:[x;*(1;0)*_mul/x#,2 2#3 1 5;1 0]}

หรือ

f:{:[x;*(1;0)*_mul/x#,(3 1;5 3);1 0]}

พวกเขาทั้งสองเหมือนกัน


0

Python 3, 49 ไบต์

w=5**0.5;a=(3+w)**int(input())//2+1;print(a,a//w)

แม้ว่าในเครื่องของฉันคำตอบนี้ให้คำตอบที่ถูกต้องสำหรับอินพุตในช่วงเท่านั้น 0 <= n <= 18เท่านั้น

สิ่งนี้ใช้สูตรฟอร์มปิด

w = 5 ** 0.5
u = 3 + w
v = 3 - w
a = (u ** n + v ** n) / 2
b = (u ** n - v ** n) / (2 * w)

และใช้ประโยชน์จากความจริงที่ว่าชิ้นv ** nส่วนมีขนาดเล็กและสามารถคำนวณได้โดยการปัดเศษแทนที่จะคำนวณโดยตรง


1
นี่ไม่ใช่วิธีแก้ปัญหาที่ถูกต้อง (คุณต้องสนับสนุนnใด ๆ) แต่เนื่องจากคุณอยู่ใกล้ที่ที่สั้นที่สุดฉันจึงไม่เห็นเหตุผลในการลงคะแนน มันเป็นทางออกที่ยอดเยี่ยม
orlp


0

C 71 ไบต์ (60 พร้อมตัวแปรเริ่มต้น)

ขอบเขตสำหรับการเล่นกอล์ฟ แต่เพียงเพื่อพิสูจน์ว่า C ไม่จำเป็นต้องเป็น "ที่น่ากลัวอย่างยิ่งยวด"

f(int n,int*a){for(*a=1,a[1]=0;n--;a[1]=*a+3*a[1],*a=(5*a[1]+4**a)/3);}

หากค่าใน a ถูกกำหนดค่าเริ่มต้นเป็น {1,0} เราทำได้ดีกว่า

f(int n,int*a){for(;n--;a[1]=*a+3*a[1],*a=(5*a[1]+4**a)/3);}

นี่เป็นการใช้การแม็พ a-> 3a + 5b, b-> a + 3b ซ้ำ ๆ แต่หลีกเลี่ยงตัวแปรชั่วคราวโดยการคำนวณ a จากค่าใหม่ของ b แทน


โซลูชันของคุณโอเวอร์
โฟลว์

@orlp - นั่นคือ C สำหรับคุณ ที่ได้รับวิธีนี้ล้มเหลวเร็วกว่าคนอื่นเพราะการคำนวณระหว่างกาลในวงเล็บ แต่มันจะจัดการขั้นตอนพิเศษไม่กี่ขั้นตอนต่อไปเว้นแต่ว่าฉันจะเปลี่ยนประเภทข้อมูล มันคุ้มค่าที่จะเปลี่ยนคำถามเพื่อให้ช่วงที่คุณคาดหวังที่จะให้การสนับสนุน? อาจจะสายเกินไปตอนนี้
เล่นแร่แปรธาตุ

ไม่มีช่วงให้การสนับสนุนทางออกที่เหมาะสมควรทำงานกับอินพุตใด ๆ ใน C นั่นหมายความว่าคุณจะต้องใช้จำนวนเต็มความกว้างตามอำเภอใจขออภัย = /
orlp

แนะนำa[*a=1]=0แทนที่จะเป็น*a=1,a[1]=0
แมวเพดาน

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