정확히 계산하기 (3 + sqrt (5)) ^ n 정확하게


23

오늘 당신의 목표는 다음 과 같이 음이 아닌 정수 n이 주어진 정수 a 와 b 를 찾는 것 입니다.

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

당신은 프로그램이나 매개 변수를받는 함수 작성해야 N을 하고 출력 와 B를 선택의 형식을.

표준 허점이 적용됩니다. 또한 기본 산술을 사용하여 위의 문제를 구현하기위한 것입니다. 따라서 내장 된 정확한 대수 기능, 이성 또는 사소한 수학적 구성을 구현하는 함수 (예 : Lucas sequence )를 사용할 수 없습니다.

바이트 단위의 최단 코드가 이깁니다.


입력 / 출력 예 :

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 년 4 월 이전에 구현되어이 답변이 유효합니다.

여기에서 시도 하십시오 . 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]있으며, 41 바이트가 아닌 26 바이트입니다.
— orlp

3
@(n)[3 5;1 3]^n*[1;0](함수 핸들)은 다섯 글자를 절약하고 좋은 아이디어를 뮤트합니다!
— flawr

14

파이썬 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

줄리아, 22 20 바이트

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

단일 정수를 입력으로 취하고 솔루션 [a, b]에 해당하는 정수로 구성된 요소를 2 개 가진 벡터를 반환하는 람다 함수를 만듭니다. 호출하려면 이름을 지정하십시오 (예 :) f=n->....

곱하여 시작

초기 확장

그런 다음이 방정식의 오른쪽을 2 열 행렬로 변환 할 수 있습니다. 첫 번째는 a 의 계수에 해당 하고 두 번째는 b 의 계수에 해당합니다 .

매트릭스

이 행렬에 n을 곱한 다음 열 벡터 (1, 0)와 POOF를 오른쪽으로 곱하십시오! 밖으로 솔루션 벡터를 팝합니다.

예 :

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시간을 곱하십시오 .

@algorithmshark 덕분에 2 바이트가 절약되었습니다.

사용 및 테스트 :

   (+/@:*(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 튜플입니다. 이 함수는로 번역됩니다 3*sum(G) + 2*G[1], sum(G) + 2*G[1]. s이다 sum, y입니다 *2.


16 분 전에 게시 된 @randomra의 답변을 선택했습니다. 죄송합니다.
— 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.
— Nit

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ᴡɴɢᴏᴀᴛ 비경쟁 답변의 경우 두 번째 줄에 바이트 수를 유지하는 것이 좋습니다. 이것은 리더 보드와 사용자 스크립트에서 답이 최상위에 오르는 것을 막아줍니다.
— Dennis


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

자바 스크립트, 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.

며칠 전에 소개 된 것 같아요?
— flawr

예, 그러나 스택 스 니펫을 엉망으로 했으므로 비활성화해야했습니다.
— Alex A.

나는 63을 그대로 세고, 61로 단축 될 수있다F=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 바이트 솔루션을 더 재미있게 보려면 (견적 : "굉장히 끔찍한") 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
이것은 다소
— 복잡한

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

어떤 이유로 f/[n;x]제대로 구현되지 않았기 때문에 Kona에서는 작동 하지 않습니다. 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

나는 더 나아지기를 바랐지만, ised에서 그것을 만들기 위해 너무 많은 괄호가 필요했습니다. 우선 순위는 골프에 최적이 아닙니다.

입력이 $ 1 메모리 슬롯에있을 것으로 예상하므로 다음과 같이 작동합니다.

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

n = 0 인 경우 0을 건너 뜁니다 (1 0 대신 1을 출력 함). 이것이 문제라면, final을 1로 바꿉니다 ~[2].


2

심각하게 32 바이트, 비경쟁

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

육각 덤프 :

2cbb34332f313260bd223b2940342af728362a2d229c6e2e58348df130606e7f

온라인으로 사용해보십시오

분명히 가장 짧은 경쟁자는 아니지만 적어도 방법은 독창적입니다. (이러한 문제는 설명에서 언급 한 것처럼 반드시 Lucas 시퀀스를 나타내므로이 프로그램은 반복 관계를 사용하여 시퀀스의 연속 항을 생성합니다.

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


1

하스켈, 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

파이썬 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

구성표, 97 바이트

(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 바이트 (사전 초기화 된 변수가있는 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);}

의 값이 {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 매핑을 반복적으로 사용하지만 대신 b의 새 값에서 a를 계산하여 임시 변수를 피합니다.


솔루션은 큰 입력에 대해 정수를 오버플로합니다. :)
— orlp

@orlp-당신을위한 C입니다. 이 솔루션은 대괄호의 중간 계산으로 인해 다른 솔루션보다 먼저 실패하지만 데이터 유형을 변경하지 않으면 몇 가지 추가 단계 만 관리합니다. 지원할 것으로 예상되는 범위를 제공하기 위해 질문을 명시 적으로 변경할 가치가 있습니까? 아마 지금 너무 늦었을 것입니다.
— Alchymist

지원할 범위가 없으며 모든 입력에 적합한 솔루션이 작동해야합니다. C에서는 임의의 너비 정수를 구현해야 함을 의미합니다. 죄송합니다 = /
— orlp

a[*a=1]=0대신 제안*a=1,a[1]=0
— 천장 고양이

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.