Tính toán (3 + sqrt (5)) ^ n chính xác


23

Hôm nay mục tiêu của bạn là tìm các số nguyên ab cho số nguyên n không âm sao cho:

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

Bạn nên viết một chương trình hoặc một hàm lấy tham số n và xuất ra ab theo định dạng bạn chọn.

Tiêu chuẩn áp dụng. Ngoài ra, dự định là bạn tự thực hiện vấn đề trên bằng cách sử dụng số học cơ bản. Vì vậy, bạn không thể sử dụng chức năng đại số chính xác, hợp lý hoặc các hàm thực hiện các cấu trúc toán học không tầm thường (ví dụ: chuỗi Lucas ).

Mã ngắn nhất trong byte thắng.


Ví dụ đầu vào / đầu ra:

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

Câu trả lời:


3

APL Dyalog, 18 byte

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

Đây là một chương trình đưa đầu vào thông qua .

 (         )         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)

Các tính năng được sử dụng ở đây đã được triển khai tốt trước tháng 4 năm 2015, làm cho câu trả lời này có hiệu lực.

Hãy thử nó ở đây . Lưu ý rằng tryapl.org là tập hợp con giới hạn của Dyalog và không hỗ trợ .


16

Octave, 26 byte

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

Bởi vì ( a + b * sqrt (5)) * (3 + sqrt (5)) = ( 3a + 5b ) + ( a + 3b ) * sqrt (5),

nhân vectơ đầu vào

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

viết tắt của 1 = (3 + sqrt (5)) ^ 0 theo ma trận

| 3 5 |
| 1 3 |

có vẻ tự nhiên Thay vì lặp nthời gian, chúng ta thay vì tăng ma trận lên lũy thừa nvà sau đó nhân nó với vectơ đầu vào.


Bạn đang bán mình ngắn, [3 5;1 3]**input('')*[1;0]là 26 byte, không phải 41.
orlp

3
@(n)[3 5;1 3]^n*[1;0] (xử lý chức năng) sẽ giúp bạn tiết kiệm năm ký tự, ý tưởng hay đấy!
flawr

14

Con trăn 2, 50

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

Bội số của 3+sqrt(5) nhiều lần bằng hành động của nó trên cặp (a,b)đại diện a+b*sqrt(5). Tương đương với bắt đầu với vectơ cột [1,0]nthời gian nhân trái của ma trận [[3,5],[1,3]].


12

Julia, 22 20 byte

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

Điều này tạo ra một hàm lambda lấy một số nguyên duy nhất làm đầu vào và trả về một vectơ 2 phần tử của các số nguyên tương ứng với giải pháp [a, b]. Để gọi nó, đặt tên cho nó, vd f=n->....

Bắt đầu bằng cách nhân

Mở rộng ban đầu

Sau đó chúng ta có thể dịch phía bên phải của phương trình này thành ma trận 2 cột, trong đó đầu tiên tương ứng với hệ số của a và thứ hai với hệ số của b :

Ma trận

Nhân ma trận này với chính nó n lần, sau đó nhân với vectơ cột (1, 0) và POOF! Ra pop vector giải pháp.

Ví dụ:

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

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

8

J, 20 byte

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

Nhân vectơ [1 0]với ma trận[[3 5] [1 3]] n lần .

2 byte được lưu nhờ vào @alerskymshark.

Sử dụng và kiểm tra:

   (+/@:*(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

Bạn có thể giảm xuống 20 bằng cách khai thác phân tích cú pháp trạng từ ngầm : +/ .*(3 5,:1 3&)&1 0.
thuật toán

@alerskymshark Cảm ơn, mặc dù tại sao (+/@:*&(3 5,.1 3)&1 0)hoạt động và (+/@:*&1 0&(3 5,.1 3))không? Không nên liên kết thứ hai một cách chính xác và liên kết đầu tiên hoán đổi?
Randomra

Có nó, họ liên kết như tôi mong đợi, nhưng bên ngoài &làm cho việc cấp nguồn / lặp để bạn sửa đổi đầu vào bên trái trong khi cấp nguồn (ngược lại với sửa đổi bên phải thông thường).
Randomra

7

Bình thường, 20 byte

u,+*3sGyeG+sGyeGQ,1Z

uđó là giảm nói chung, được sử dụng ở đây như là một vòng lặp áp dụng nhiều lần. Chức năng cập nhật là G-> ,+*3sGyeG+sGyeG, trong đó Glà 2 tuple. Hàm đó dịch sang 3*sum(G) + 2*G[1], sum(G) + 2*G[1]. ssum, y*2.


Tôi đã chọn câu trả lời của @ Randomra thay vì câu trả lời của anh ấy / cô ấy đã được đăng 16 phút trước đó, xin lỗi.
orlp

5

APL (22)

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

Giải trình:

  • {... }⍣⎕⍨2↑1: đọc một số và chạy hàm sau nhiều lần, sử dụng [1,0]làm đầu vào ban đầu.
    • 2 2⍴3 5 1: ma trận [[3,5],[1,3]]
    • ⍵+.×⍨: nhân số thứ nhất trong với 3, số thứ hai với 5 và tính tổng chúng, đây là số thứ nhất mới; sau đó nhân số thứ nhất trong với 1, số thứ hai với 3 và tính tổng số đó, đó là số thứ hai mới.

1
Awww, APL.
Nit

5

Thạch , 13 byte

5W×U++Ḥ
2Bdz¡

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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.

Không, tôi khá chắc chắn Jelly đã tồn tại một thời gian dài trước khi tạo ra internet: P
Conor O'Brien

1
@ Doᴡɴɢᴏᴀᴛ Đối với các câu trả lời không cạnh tranh, tôi thích giữ số byte trên dòng thứ hai. Điều này giữ cho câu trả lời từ tăng lên hàng đầu trong bảng xếp hạng và bảng mô tả người dùng, có vẻ không công bằng.
Dennis


3

CJam, 21 byte

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

Hãy thử trực tuyến.

Làm thế nào nó hoạt động

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 byte

Tôi đang sử dụng một đánh giá đệ quy của nhị thức: (x + y) ^ n = (x + y) (x + y) ^ {n-1}

Mới (nhờ @ 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
Có thể muốn xem xét chỉnh sửa công thức của bạn. Chúng ta không có MathJax nữa.
Alex A.

Tôi nghĩ rằng nó chỉ được giới thiệu một vài ngày trước?
flawr

Vâng, nhưng nó đã làm rối các đoạn stack, vì vậy nó phải bị vô hiệu hóa.
Alex A.

Tôi đếm 63 như hiện tại và có thể rút ngắn xuống còn 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]cùng chiều dài
l4m2

2

C, 114 byte

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]);}

Điều này thực hiện nhân ma trận một cách nhàm chán. Đối với một niềm vui hơn (trích dẫn: "khủng khiếp khủng khiếp") giải pháp 238 byte, không tìm đâu xa!

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]);}

Làm sáng tỏ:

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]);
}

Điều này có lẽ có thể được rút ngắn một chút. Hãy thử một chương trình thử nghiệm trực tuyến !


1
Đây là sử dụng một thuật toán khá phức tạp: P
orlp

@orlp Tôi không thể nghĩ ra một thuật toán ngắn hơn cho ngôn ngữ này. Tôi nghĩ cái này sẽ hoạt động được, nhưng nó đã vượt quá tầm tay, haha. Việc thực hiện nhân ma trận bằng tay rất có thể ngắn hơn.
BrainSteel

1
Upvote bởi vì điều này là khủng khiếp khủng khiếp.
kirbyfan64sos

2

k2 - 22 char

Hàm lấy một đối số.

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

_mullà phép nhân ma trận, vì vậy chúng tôi curry nó với ma trận (3 5;1 3)và sau đó nhấn nó với trạng từ sức mạnh chức năng: f/[n;x]áp dụng fcho x, nlần. Một lần nữa chúng ta cà ri nó, lần này với vector bắt đầu 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)

Điều này sẽ không hoạt động ở Kona, vì một số lý do f/[n;x]không được triển khai chính xác. Chỉ n f/xcú pháp hoạt động, vì vậy sửa chữa ngắn nhất là {x _mul[(3 5;1 3)]/1 0}ở 23 char.


Ồ Cách sử dụng cà ri này rất thông minh Tôi cảm thấy câu trả lời K của mình thật ngu ngốc. Dù sao, tôi đã nêu ra vấn đề bạn tìm thấy ở Kona trên trình theo dõi lỗi của họ .
kirbyfan64sos


2

25 byte (20 ký tự)

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

Tôi hy vọng tốt hơn, nhưng có quá nhiều niềng răng cần thiết để làm cho nó có thẩm quyền, ưu tiên người vận hành là không tối ưu cho việc chơi golf.

Nó hy vọng đầu vào nằm trong khe nhớ $ 1, vì vậy điều này hoạt động:

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

Với n = 0, số 0 được bỏ qua (đầu ra 1, thay vì 1 0). Nếu đó là một vấn đề, thay thế cuối cùng 1với ~[2].


2

Nghiêm túc, 32 byte, không cạnh tranh

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

Bãi rác Hex:

2cbb34332f313260bd223b2940342af728362a2d229c6e2e58348df130606e7f

Dùng thử trực tuyến

Rõ ràng không phải là một ứng cử viên cho ngắn nhất, nhưng ít nhất phương pháp là bản gốc. (Lưu ý rằng một vấn đề như vậy nhất thiết chỉ ra một chuỗi Lucas, như được đề cập trong mô tả, chương trình này tạo ra các thuật ngữ liên tiếp của các chuỗi sử dụng mối quan hệ lặp lại

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


1

Haskell, 41 byte

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

Ví dụ sử dụng: (iterate(\(a,b)->(3*a+5*b,a+3*b))(1,0)!!) 8-> (282496,126336).


1

C / C ++ 89 byte

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

Định dạng:

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

Khái niệm tương tự:

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

Bàn thử nghiệm:

#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;
}

Đầu ra:

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

Chào mừng đến với trang web, và câu trả lời đầu tiên tốt đẹp!
DJMcMayhem

0

K, 37 byte

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

hoặc là

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

Cả hai đều giống nhau.


0

Python 3, 49 byte

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

mặc dù trên máy của tôi, điều này chỉ đưa ra câu trả lời chính xác cho các đầu vào trong phạm vi 0 <= n <= 18.

Điều này thực hiện công thức dạng đóng

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

và lợi dụng thực tế là v ** nphần đó nhỏ, và có thể được tính bằng cách làm tròn hơn là tính toán trực tiếp.


1
Đây không phải là một giải pháp hợp lệ (bạn phải hỗ trợ bất kỳ n ), nhưng vì bạn gần như không phải là người ngắn nhất nên tôi không thấy lý do gì để hạ thấp. Đó là một giải pháp tuyệt vời.
orlp

0

Lược đồ, 97 byte

(define(r n)(let s([n n][a 1][b 0])(if(= 0 n)(cons a b)(s(- n 1)(+(* a 3)(* b 5))(+ a(* b 3))))))

0

C 71 byte (60 với các biến được khởi tạo trước)

Phạm vi để chơi golf chưa nhưng chỉ để chứng minh rằng C không phải là "khủng khiếp khủng khiếp".

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);}

Nếu các giá trị trong a được khởi tạo thành {1,0}, chúng tôi sẽ làm tốt hơn.

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

Đây là lặp đi lặp lại bằng cách sử dụng ánh xạ a-> 3a + 5b, b-> a + 3b nhưng tránh một biến tạm thời bằng cách tính a từ giá trị mới của b thay vào đó.


Giải pháp của bạn vượt quá số nguyên cho đầu vào lớn :)
orlp

@orlp - Đó là C dành cho bạn. Cấp giải pháp này thất bại sớm hơn các giải pháp khác vì tính toán tạm thời trong ngoặc nhưng nó sẽ chỉ quản lý một vài bước bổ sung trừ khi tôi thay đổi kiểu dữ liệu. Có đáng để thay đổi rõ ràng câu hỏi để đưa ra phạm vi bạn muốn hỗ trợ không? Có lẽ bây giờ đã quá muộn.
Alchymist

Không có phạm vi để hỗ trợ, một giải pháp thích hợp sẽ hoạt động cho bất kỳ đầu vào nào. Trong C có nghĩa là bạn sẽ phải triển khai các số nguyên chiều rộng tùy ý, xin lỗi = /
orlp

Đề xuất a[*a=1]=0thay vì*a=1,a[1]=0
trần

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.