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


23

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

(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]적용 fx, 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.