Послідовність скарбничок


14

Нещодавно я створив свою власну послідовність (називається послідовністю Piggyback), і вона працює так:

P(1), P(2)і P(3)= 1.

Для всіх, P(n)де n>3послідовність працює так:

P(n) = P(n-3) + P(n-2)/P(n-1)

Отже, продовжуючи послідовність:

P(4)= 1 + 1/1=2

P(5)= 1 + 1/2= 3/2 =1.5

P(6)= 1 + 2/(3/2)= 7/3 =2.33333...

P(7)= 2 + (3/2)/(7/3)= 37/14=2.6428571428...

P(8)= 3/2 + (7/3)/(37/14)= 529/222 =2.3828828828...

Ваше завдання, якщо дано n, обчислити P(n)або число з плаваючою комою, або як (не) власний дріб.

Це , тому найкоротший код у байтах виграє.

Якщо хтось може знайти назву послідовності, будь ласка, відредагуйте повідомлення відповідно.

Поточні лідери: MATL та Jelly (обидва по 15 байт).


Чи можемо ми починати з індексу 0? P(0)=1...
німі

3
Чи можу я попросити обґрунтування імені, яке ви дали цій послідовності?
Джон Дворак

@JanDvorak Просто схоже, що цифри "підробляють" один одного.
клісмік

@nimi Так, вам дозволено.
клісмік

Відповіді:


6

Python 2, 40 39 байт.

f=lambda x:x<4or.0+f(x-3)+f(x-2)/f(x-1)

Дає Trueзамість 1, якщо це не дозволено, ми можемо мати це на 42 байти:

f=lambda x:.0+(x<4or f(x-3)+f(x-2)/f(x-1))

Те, як це працює, досить просте, єдиний трюк - це використовувати, .0+щоб передати результат плаву.


Ви можете зберегти один байт, видаливши пробіл між x<4іor
acrolith

У Python 2 ви можете використовувати f(x-1.)для керування плавати. У Python 3 взагалі не потрібно брати участь у програмі.
Денніс

5

Хаскель, 32 байти

(a#b)c=a:(b#c)(a+b/c)
((0#1)1!!)

Приклад використання: ((0#1)1!!) 7 -> 2.642857142857143. Я починаю послідовність з того, 0, 1, 1щоб виправити !!індексацію на основі 0.

Редагувати: @xnor знайшов спосіб перейти з 0-базова на 1-індекс, не змінюючи кількість байтів.


1
Хороший метод побиття прямого рекурсивного визначення. Я думаю, що ви можете перейти до 1-індексу шляхом ініціалізації (0,1,1).
xnor

4

Рубін, 34 байти

Оскільки Рубі за замовчуванням використовує цілочисельний поділ, виявляється, що замість цього використовувати дроби коротше. Пропозиції з гольфу вітаються.

f=->n{n<4?1r:f[n-3]+f[n-2]/f[n-1]}

4

Perl 6 ,  25  23 байти

{(0,1,1,1,*+*/*...*)[$_]}

{(0,1,1,*+*/*...*)[$_]}

Пояснення:

# bare block lambda with implicit parameter 「$_」
{
  (
    # initial set-up
    # the 「0」 is for P(0) which isn't defined
    0, 1, 1, 1,

    # Whatever lambda implementing the algorithm
    * + * / *
    # { $^a + $^b / $^c }

    # keep using the lambda to generate new values until
    ...

    # Whatever (Forever)
    *

   # get the value indexed by the argument
  )[ $_ ]
}

Це повертає Щур ( Раціональний ) для входів, починаючи з 3 вгору, поки результат не почне мати знаменник, більший, ніж може вміститися в 64-бітове ціле число, після чого він починає повертати Num s (плаваюча точка).
Останній Щур, який вона поверне, - цеP(11) == 8832072277617 / 2586200337022

Якщо ви хочете, щоб він повертав раціональні числа, а не плаваючі, ви можете поміняти його на наступне, що натомість поверне FatRat .

{(0.FatRat,1,1,*+*/*...*)[$_]}

Тест:

#! /usr/bin/env perl6
use v6.c;
use Test;

my &piggyback = {(0,1,1,*+*/*...*)[$_]}
# */ # stupid highlighter no Perl will ever have C/C++ comments

my @test = (
  1, 1, 1, 2,
  3/2, 7/3, 37/14,
  529 / 222,
  38242 / 11109,
  66065507 / 19809356,
  8832072277617 / 2586200337022,
);

plan +@test;

for 1..* Z @test -> ($input,$expected) {
  cmp-ok piggyback($input), &[==], $expected, $expected.perl;
}


3

MATL , 15 байт

llli3-:"3$t/+]&

Спробуйте в Інтернеті!

Пояснення

lll       % Push 1, 1, 1
i         % Take input n
3-:       % Pop n and push range [1 2 ... n-3] (empty if n<4)
"         % For each
  3$t     %    Duplicate the top three numbers in the stack
  /       %    Pop the top two numbers and push their division
  +       %    Pop the top two numbers and push their addition
]         % End
&         % Specify that the next function, which is implicit display, will take
          % only one input. So the top of the stack is displayed

2

Чеддар , 31 байт

n P->n<4?1:P(n-3)+P(n-2)/P(n-1)

Необоротна версія настільки зрозуміла, що вам не потрібно пояснення:

n P->
  n < 4 ? 1 : P(n-3) + P(n-2) / P(n-1)

в основному після аргументів функції ви можете вказати змінну, для використання якої буде встановлена ​​сама функція. Чому? тому що ця функція буде оптимізована для хвостового виклику або, принаймні, повинна бути.


2

Javascript (ES6), 31 байт

P=n=>n<4?1:P(n-3)+P(n-2)/P(n-1)

Проста функція.

P=n=>n<4?1:P(n-3)+P(n-2)/P(n-1)

var out = '';

for (var i=1;i <= 20;i++) {
out +='<strong>'+i+':</strong> '+P(i)+'<br/>';
}

document.getElementById('text').innerHTML = out;
div {
font-family: Arial
}
<div id="text"></div>


Чому б не ES6? Це економить метричну тону байтів.
Ісмаїл Мігель

Ось так:P=n=>n<4?1:P(n-3)+P(n-2)/P(n-1)
Ісмаель Мігель

@IsmaelMiguel Дякую Чесно кажучи, я не маю уявлення про різницю між різними Javascripts: D
Beta Decay

На вашу користь, у більшості викликів вам потрібно знати лише «Позначення великої стрілки», яке дозволяє створювати функції без використання ключового слова function. Біт P=n=>[...]створює анонімну функцію, яка приймає 1 параметр (n). Також у ES6 повернення є неявними. Отже, P=n=>5це функція, яка завжди повертається 5. Тіло потрібно укласти, {}якщо у вас є більше одного твердження (наприклад:) P=n=>{alert(1);console.log(1)}. Оскільки у вас є лише 1 (великий) оператор (потрійний оператор), ви можете забути це {}.
Ісмаїл Мігель

@IsmaelMiguel Дякую, що стане в нагоді: D
бета-розпад

2

05AB1E , 18 17 байт

3Ld                # push list [1,1,1]
   ¹ÍG         }   # input-3 times do
      D3£          # duplicate list and take first 3 elements of the copy
         R`        # reverse and flatten
           /+      # divide then add
             ¸ì    # wrap in list and prepend to full list
                ¬  # get first element and implicitly print

Спробуйте в Інтернеті!

Збережено 1 байт завдяки Луїсу Мендо



1

Желе , 15 байт

ạ2,1,3߀÷2/SµḊ¡

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

ạ2,1,3߀÷2/SµḊ¡  Main link. Argument: n (integer)

             Ḋ   Dequeue; yield [2, ..., n].
            µ ¡  If the range is non-empty (i.e., if n > 1), execute the chain to
                 the left. If n is 0 or 1, return n.
                 Note that P(3) = P(0) + P(2)/P(1) if we define P(0) := 0.
ạ2,1,3           Take the absolute difference of n and 2, 1, and 3.
                 This gives [0, 1, 1] if n = 2, and P(0) + P(1)/P(1) = 0 + 1/1 = 1.
      ߀         Recursively apply the main each to each difference.
        ÷2/      Perform pairwise division.
                 This maps [P(n-2), P(n-1), P(n-3)] to [P(n-2)/P(n-1), P(n-3)].
           S     Sum, yielding P(n-2)/P(n-1) + P(n-3).

1

R, 53 47 байт

f=function(N)ifelse(N>3,f(N-3)+f(N-2)/f(N-1),1)

У цій відповіді було використано досить акуратну функцію ifelse:ifelse(Condition, WhatToDoIfTrue, WhatToDoIfNot)


1
Ви повинні мати змогу позбутися цього return()коду. Але вам також потрібно назвати функцію, щоб ваша рекурсія працювала
user5957401

0

Математика, 36 байт

P@n_:=If[n<4,1,P[n-3]+P[n-2]/P[n-1]]

Ось кілька перших термінів:

P /@ Range[10]
{1, 1, 1, 2, 3/2, 7/3, 37/14, 529/222, 38242/11109, 66065507/19809356}

0

Діалог APL, 25 байт

⊃{1↓⍵,⍎⍕' +÷',¨⍵}⍣⎕⊢0 1 1

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