The Piggyback Sequence

14

J'ai fait ma propre séquence récemment (appelée la séquence Piggyback), et cela fonctionne comme ceci:

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

Pour tous P(n)n>3, la séquence fonctionne comme ceci:

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

Donc, continuant la séquence:

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...

Votre tâche consiste, une fois donnée n, à calculer P(n)soit un nombre à virgule flottante, soit une fraction (im) appropriée.

C'est le , donc le code le plus court en octets gagne.

Si quelqu'un peut trouver le nom de la séquence, veuillez modifier le message en conséquence.

Leaders actuels: MATL et Jelly (tous deux à 15 octets).

clismique
la source
Pouvons-nous commencer à l'indice 0? P(0)=1...
nimi
3
Puis-je demander la justification du nom que vous avez donné à cette séquence?
John Dvorak
@JanDvorak Il semble que les chiffres se "superposent".
clismique
@nimi Oui, vous êtes autorisé.
clismique

Réponses:

6

Python 2, 40 39 octets.

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

Donne Trueau lieu de 1, si cela n'est pas autorisé, nous pouvons avoir ceci pour 42 octets:

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

La façon dont cela fonctionne est assez simple, la seule astuce consiste .0+à lancer le résultat sur un flottant.

Loovjo
la source
Vous pouvez économiser un octet en supprimant l'espace entre x<4etor
acrolith
Dans Python 2, vous pouvez utiliser f(x-1.)pour lancer pour flotter. Dans Python 3, vous n'avez pas besoin de caster du tout.
Dennis
5

Haskel, 32 octets

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

Exemple d'utilisation: ((0#1)1!!) 7-> 2.642857142857143. Je démarre la séquence avec 0, 1, 1pour corriger !!l'indexation basée sur 0.

Edit: @xnor a trouvé un moyen de passer d'un index basé sur 0 à un index basé sur 1, sans changer le nombre d'octets.

nimi
la source
1
Belle méthode pour battre la définition récursive directe. Je pense que vous pouvez passer à 1 indexé en initialisant (0,1,1).
xnor
4

Rubis, 34 octets

Puisque Ruby utilise la division entière par défaut, il s'avère qu'il est plus court d'utiliser des fractions à la place. Suggestions de golf bienvenues.

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

Perl 6 ,  25  23 octets

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

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

Explication:

# 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
  )[ $_ ]
}

Cela renvoie un Rat ( rationnel ) pour les entrées commençant par 3 jusqu'à ce que le résultat commence à avoir un dénominateur plus grand que ce qui peut tenir dans un entier 64 bits, point auquel il commence à renvoyer Num s (virgule flottante).
Le dernier rat qu'il reviendra estP(11) == 8832072277617 / 2586200337022

Si vous voulez qu'il retourne des nombres rationnels plutôt que des flottants, vous pouvez l'échanger contre ce qui va retourner un FatRat à la place.

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

Tester:

#! /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;
}
Brad Gilbert b2gills
la source
3

C, 46 octets

float P(n){return n<4?1:P(n-3)+P(n-2)/P(n-1);}

Ideone

betseg
la source
3

MATL , 15 octets

llli3-:"3$t/+]&

Essayez-le en ligne!

Explication

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
Luis Mendo
la source
2

Cheddar , 31 octets

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

La version non golfée est si claire que vous n'avez pas besoin d'explication:

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

fondamentalement, après les arguments de la fonction, vous pouvez spécifier la variable à utiliser qui sera définie sur la fonction elle-même. Pourquoi? parce que cette fonction sera optimisée pour les appels de queue, ou du moins devrait l'être.

Downgoat
la source
2

Javascript (ES6), 31 octets

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

Une fonction simple.

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>

Beta Decay
la source
Pourquoi pas ES6? Il enregistre une tonne métrique d'octets.
Ismael Miguel
Comme ça:P=n=>n<4?1:P(n-3)+P(n-2)/P(n-1)
Ismael Miguel
@IsmaelMiguel Merci. Franchement, je n'ai aucune idée de la différence entre les différents Javascripts: D
Beta Decay
À votre avantage, sur la plupart des défis, il vous suffit de connaître la "notation Big Arrow", qui vous permet de créer des fonctions sans utiliser le mot-clé function. Le bit P=n=>[...]crée une fonction anonyme qui prend 1 paramètre (n). De plus, sur ES6, les retours sont implicites. Donc, P=n=>5c'est une fonction qui revient toujours 5. Vous ne devez enfermer le corps que {}si vous avez plusieurs déclarations (par exemple:) P=n=>{alert(1);console.log(1)}. Puisque vous n'avez qu'une seule (grande) instruction (l'opérateur ternaire), vous pouvez oublier le {}.
Ismael Miguel
@IsmaelMiguel Merci, cela vous sera utile: D
Beta Decay
2

05AB1E , 18 17 octets

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

Essayez-le en ligne!

1 octet enregistré grâce à Luis Mendo

Emigna
la source
1

Gelée , 15 octets

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

Essayez-le en ligne! ou vérifier tous les cas de test .

Comment ça fonctionne

ạ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).
Dennis
la source
1

R, 53 47 octets

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

Cette réponse a utilisé la fonction assez soignée ifelse:ifelse(Condition, WhatToDoIfTrue, WhatToDoIfNot)

Frédéric
la source
1
Vous devriez pouvoir vous en débarrasser return()dans votre code. Mais vous devez également nommer la fonction pour que votre récursivité fonctionne
user5957401
0

Mathematica, 36 octets

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

Voici les premiers termes:

P /@ Range[10]
{1, 1, 1, 2, 3/2, 7/3, 37/14, 529/222, 38242/11109, 66065507/19809356}
phosgène
la source
0

Dyalog APL, 25 octets

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

ngn
la source