Tam olarak hesaplanıyor (3 + sqrt (5)) ^ n


23

Bugün hedef tamsayılar bulmaktır bir ve b verilen negatif olmayan tamsayı n öyle ki:

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

N parametresini alan ve istediğiniz formatta a ve b çıktılarını veren bir program veya işlev yazmalısınız .

Standart boşluklar uygulanır. Ek olarak, yukarıdaki aritmetiği kullanarak kendiniz yukarıdaki problemi uygulamanız amaçlanmıştır. Dolayısıyla, yerleşik tam cebir işlevlerini, rasyonelleri veya önemsiz olmayan matematiksel yapıları uygulayan işlevleri (örneğin, Lucas dizisi ) kullanamazsınız .

Bayt cinsinden en kısa kod kazanır.


Örnek giriş / çıkış:

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

Yanıtlar:


3

Dyalog APL, 18 bayt

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

Bu, girdi alan bir programdır .

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

Burada kullanılan özellikler, Nisan 2015'ten önce iyi bir şekilde uygulanmış ve bu cevabı geçerli kılmıştır.

Burada dene . Tryapl.org'un sınırlı bir Dyalog alt kümesi olduğunu ve desteklemediğini unutmayın .


16

Octave, 26 bayt

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

Çünkü ( a + b * sqrt (5)) * (3 + sqrt (5)) = ( 3a + 5b ) + ( a + 3b ) * sqrt (5),

çarpım girişi vektörü

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

matris tarafından 1 = (3 + sqrt (5)) ^ 0 anlamına gelir

| 3 5 |
| 1 3 |

doğal görünüyor. Döngü nzamanları yerine, matrisi gücüne yükseltiriz nve sonra onu giriş vektörüyle çarparız.


Kendinizi kısa satıyorsunuz [3 5;1 3]**input('')*[1;0], 26 bayt, 41 değil.
or

3
@(n)[3 5;1 3]^n*[1;0](işlev kolu) size beş karakter kazandıracak, iyi fikir!
kusur

14

Python 2, 50

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

Temsil 3+sqrt(5)eden çift üzerindeki eylemi ile art arda çarpılır . Sütun vektörüyle başlayan ve matris tarafından sola çarpma sürelerine eşdeğerdir .(a,b)a+b*sqrt(5)[1,0]n[[3,5],[1,3]]


12

Julia, 22 20 bayt

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

Bu, giriş olarak tek bir tam sayı alan ve çözüme [a, b] karşılık gelen tam sayıların 2 elemanlı bir vektörünü döndüren bir lambda işlevi yaratır. Aramak için bir isim verin, örneğin f=n->....

Çarparak başlayın

Initial expand

Daha sonra bu denklemin sağ tarafını 2 sütunlu bir matrise çevirebiliriz; burada birincisi a katsayısına , ikincisi b katsayısına karşılık gelir :

Matrix

Bu matrisi n kere çarp , sonra sağdaki sütun vektörünü (1, 0) ve POOF! Dışarı çözüm vektörünü çıkar.

Örnekler:

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

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

8

J, 20 bayt

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

Vektörü [1 0]matris [[3 5] [1 3]] nzamanlarıyla çarpın.

@Algorithmshark sayesinde 2 bayt kurtarıldı.

Kullanım ve test:

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

Sen zımni zarf ayrıştırılmasını istismar ederek 20 aşağı alabilirsiniz: +/ .*(3 5,:1 3&)&1 0.
algorithmshark

@algorithmshark sayesinde, neden her ne kadar (+/@:*&(3 5,.1 3)&1 0)çalışır ve (+/@:*&1 0&(3 5,.1 3))değil? İkincisi doğru şekilde bağlanmış ve birincisi değiştirilmemeli midir?
randomra

Anladım, beklediğim gibi bağlanıyorlar ancak dış &güç / döngü yapıyor, böylece güç sırasında sol taraftaki girişi değiştiriyorsunuz (normal sağ taraf değişikliklerinin karşısında).
randomra

7

Pyth, 20 bayt

u,+*3sGyeG+sGyeGQ,1Z

uGenel olarak azaltılmış olan, burada tekrar tekrar döngü uygulamak için kullanılır. Güncelleme işlevi G-> ,+*3sGyeG+sGyeGolup G, 2 tuple. Bu işlev için çevirir 3*sum(G) + 2*G[1], sum(G) + 2*G[1]. solduğu sum, yolduğunu *2.


@ Randomra'nın senin cevabını seçtim çünkü onunkiler 16 dakika önce gönderildi, pardon.
orlp

5

APL (22)

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

Açıklama:

  • {... }⍣⎕⍨2↑1: bir sayı okuyun ve aşağıdaki işlevi [1,0]ilk giriş olarak kullanarak birçok kez çalıştırın .
    • 2 2⍴3 5 1: matris [[3,5],[1,3]]
    • ⍵+.×⍨: ilk sayıyı in ile 3, ikinciyi 5 ile çarpın ve toplayın, bu yeni ilk sayıdır; daha sonra, ilk sayıyı 1 ile 1 ile, çarpımı 3 ile çarp ve bunları topla, yani yeni ikinci sayı.

1
Awww yiss, APL.
Nit

5

Jöle , 13 bayt

5W×U++Ḥ
2Bdz¡

Çevrimiçi deneyin!

Nasıl çalışır

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.

Hayır, Jelly internetin oluşturulmasından çok uzun zaman önce bulunduğundan eminim: P
Conor O'Brien

1
@ Doᴡɴɢᴏᴀᴛ Yarışması olmayan cevaplar için bayt sayısını ikinci satırda tutmayı tercih ederim. Bu, haksız görünen lider tablolarında ve kullanıcı açıklamalarında cevabın en üste çıkmasını önlüyor.
Dennis


3

CJam, 21 bayt

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

Çevrimiçi deneyin.

Nasıl çalışır

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 bayt

Binom özyinelemeli bir değerlendirme kullanıyorum: (x + y) ^ n = (x + y) (x + y) ^ {n-1}

Yeni (@ edc65 sayesinde)

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

Eski

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

1
Formülünüzü düzenlemeyi düşünebilirsiniz. Artık MathJax'ımız yok.
Alex A.

Birkaç gün önce tanıtıldığını sanıyordum?
kusur

Evet, ama yığın parçacıklarını mahvetti, bu yüzden devre dışı bırakılması gerekiyordu.
Alex A.

63 olduğu gibi sayıyorum ve 61 ile kısaltılabilirimF=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]aynı uzunluk
l4m2

2

C, 114 bayt

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

Bu matris çarpımını sıkıcı şekilde uygular. Daha eğlenceli (alıntı: "korkunç derecede korkunç") 238 baytlık çözüm, daha fazla kendinizi yormayın!

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

sökülmüş:

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

Bu muhtemelen biraz kısaltılabilir. Online bir test programı deneyin !


1
Bu oldukça karmaşık bir algoritma kullanır: P
orlp

@ orlp bu dil için daha kısa bir algoritma düşünemedim. Bunun işe yarayacağını düşünmüştüm, ama bir nevi elden çıkmış haha. Matris çarpımını elle uygulamak çok daha kısa olabilir.
BrainSteel

1
Olumlu oy çünkü bu korkunç derecede korkunç.
kirbyfan64sos

2

k2 - 22 karakter

Bir argüman alarak işlev.

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

_mulmatriks ile köri böylece matris çarpım olduğu (3 5;1 3): ve daha sonra fonksiyonel güç zarf ile vurmak f/[n;x]geçerlidir füzere x, nkat. Yine bu sefer başlangıç ​​vektörü ile köreliyoruz 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)

Bu, Kona'da çalışmayacak, çünkü bir nedenden dolayı f/[n;x]doğru bir şekilde uygulanmadı. Yalnızca n f/xsözdizimi çalışır, bu nedenle en kısa düzeltme {x _mul[(3 5;1 3)]/1 0}23 karakterdedir.


Vay. Körlemenin bu kullanımı o kadar akıllı ki K cevabım aptalmış gibi hissediyorum. Her neyse, Kona'da bulduğun sorunu böcek izleyicilerinde gündeme getirdim .
kirbyfan64sos


2

ised, 25 bayt (20 karakter)

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

Daha iyisini ümit ediyordum, ancak bunu yetkin hale getirmek için ised'de ihtiyaç duyulan çok fazla parantez var, operatör önceliği golf oynamak için uygun değil.

Girişin $ 1 bellek yuvasında olmasını bekliyor, bu yüzden işe yarıyor:

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

N = 0 için sıfır atlanır (1 0 yerine 1 çıkışı). Bu bir sorunsa, finali 1ile değiştirin ~[2].


2

Cidden, 32 bayt, rakipsiz

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

Hex Dump:

2cbb34332f313260bd223b2940342af728362a2d229c6e2e58348df130606e7f

Deneyin Onlline

Açıkçası en kısa süren bir rakip değil, en azından yöntem orijinal. (Böyle bir sorunun mutlaka açıklamasında belirtildiği gibi bir Lucas sırasını gösterdiğine dikkat ederek, bu program tekrarlama ilişkisini kullanan sıralı terimleri üretir.

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


1

Haskell, 41 bayt

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

Kullanım örneği: (iterate(\(a,b)->(3*a+5*b,a+3*b))(1,0)!!) 8-> (282496,126336).


1

C / C ++ 89 bayt

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

biçimlendirilmiş:

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

Aynı kavram:

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

Test tezgahı:

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

Çıktı:

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

Siteye Hoşgeldiniz ve güzel ilk cevap!
DJMcMayhem

0

K, 37 bayt

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

veya

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

İkisi de aynı şey.


0

Python 3, 49 bayt

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

benim makinede olmasına rağmen, bu yalnızca aralıktaki girişler için doğru cevabı verir 0 <= n <= 18.

Bu kapalı formülü uygular

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

ve v ** nparçanın küçük olması ve doğrudan hesaplama yerine yuvarlama ile hesaplanabilmesi gerçeğinden faydalanır .


1
Bu geçerli bir çözüm değil (herhangi bir n'i desteklemelisiniz ), ancak en yakın olduğunuza yakın olduğunuzdan, oy kullanmamak için bir neden göremiyorum. Harika bir çözüm.
orlp

0

Şema, 97 bayt

(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 bayt (önceden başlatılmış değişkenleri olan 60)

Henüz golf oynamak için değil, sadece C'nin "korkunç derecede korkunç" olması gerekmediğini kanıtlamak için.

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 içindeki değerler {1,0} olarak başlatılmışsa, daha iyisini yaparız.

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

Bu, yinelemeli olarak a-> 3a + 5b, b-> a + 3b eşlemelerini kullanıyor, ancak bunun yerine yeni b değerinden a hesaplayarak geçici bir değişkenden kaçınıyor.


Çözümünüz büyük girdiler için tamsayıları
aşar

@orlp - Bu senin için C. Verilen çözüm, parantez içindeki geçici hesaplamalardan ötürü diğerlerinden daha önce başarısız oluyor ancak veri türünü değiştirmediğim sürece sadece birkaç ekstra adım uygulayabiliyordu. Desteklemeyi beklediğiniz aralığı vermek için soruyu açıkça değiştirmeye değer mi? Muhtemelen şimdi çok geç.
Simyacı

Destekleyecek bir alan yok, herhangi bir girdi için uygun bir çözüm çalışması gerekiyor. Bu, C'de isteğe bağlı genişlikli tamsayıları uygulamanız gerektiği anlamına gelir, üzgünüm = /
orlp 14.05.09

Öner a[*a=1]=0yerine*a=1,a[1]=0
ceilingcat

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.