Обчислення (3 + sqrt (5)) ^ n точно


23

Сьогодні ваша мета - знайти цілі числа a і 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

Діалог 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.
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]

Це створює лямбда-функцію, яка приймає одне ціле число як вхідне і повертає 2-елементний вектор цілих чисел, відповідний розв’язку [a, b]. Щоб зателефонувати, дайте ім’я, наприклад f=n->....

Почніть з множення

Initial expand

Потім ми можемо перевести праву частину цього рівняння в матрицю з двома стовпцями, де перша відповідає коефіцієнту a, а друга - коефіцієнту b :

Matrix

Помножте цю матрицю на себе 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рази.

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 Спасибі, хоча чому (+/@:*&(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, де Gє два кортежі. Ця функція перекладається на 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 більше немає.
Олексій А.

Я думав, що це було запроваджено кілька днів тому?
flawr

Так, але це переплутало фрагменти стека, тому його довелося відключити.
Олексій А.

Я рахую 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

@orlp Я не міг придумати коротший алгоритм для цієї мови. Я думав, що це вийде, але це щось вийшло з рук, ха-ха. Реалізація матричного множення вручну цілком може бути коротшою.
BrainSteel

1
Оновлення, оскільки це надзвичайно жахливо.
kirbyfan64sos

2

k2 - 22 char

Функція, що бере один аргумент.

_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]не виконано правильно. n f/xПрацює лише синтаксис, тому найкоротший виправлення - це {x _mul[(3 5;1 3)]/1 0}23 знаки.


Ого. Це використання currying настільки розумне, я вважаю, що моя відповідь K дурна. У всякому разі, я порушив проблему, яку ви знайшли в Коні на їхньому трекері помилок .
kirbyfan64sos


2

об'єм, 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

К, 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

Схема, 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);}

Якщо значення в 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, але уникаючи тимчасової змінної, обчислюючи натомість нове значення b.


Ваше рішення переповнює цілі числа для великих входів :)
orlp

@orlp - Це для вас. Це рішення не вдається раніше, ніж інші, через проміжний розрахунок у дужках, але воно все одно керуватиме лише декількома додатковими кроками, якщо я не зміню тип даних. Чи варто чітко змінити питання, щоб дати діапазон, який ви очікуєте на підтримку? Напевно, зараз занадто пізно.
Алхімік

Немає діапазону для підтримки, правильне рішення повинно працювати для будь-якого введення. В C це означає, що вам доведеться реалізувати довільну ширину цілих чисел, вибачте = /
orlp

Запропонувати a[*a=1]=0замість*a=1,a[1]=0
roofcat

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.