Die Piggyback-Sequenz

14

Ich habe kürzlich eine eigene Sequenz (Piggyback-Sequenz) erstellt, die wie folgt funktioniert:

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

Für alle, P(n)wo n>3funktioniert die Sequenz wie folgt:

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

So setzen Sie die Sequenz fort:

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

Ihre Aufgabe ist es, wenn gegeben n, P(n)entweder als Gleitkommazahl oder als (im) richtigen Bruch zu berechnen.

Das ist , also gewinnt der kürzeste Code in Bytes.

Wenn jemand den Namen der Sequenz finden kann, bearbeiten Sie den Beitrag entsprechend.

Aktuelle Anführer: MATL und Jelly (beide mit 15 Bytes).

Clismique
quelle
Können wir bei Index 0 beginnen? P(0)=1...
nimi
3
Darf ich nach dem Grund für den Namen fragen, den Sie dieser Sequenz gegeben haben?
John Dvorak
@JanDvorak Es scheint nur, als würden sich die Zahlen gegenseitig "huckepack nehmen".
Clismique
@nimi Ja, du darfst.
Clismique

Antworten:

6

Python 2, 40 39 Bytes.

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

Gibt Trueanstelle von 1, wenn dies nicht erlaubt ist, können wir dies für 42 Bytes haben:

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

Die Art und Weise, wie es funktioniert, ist ziemlich unkompliziert. Der einzige Trick besteht .0+darin, das Ergebnis in einen Float umzuwandeln.

Loovjo
quelle
Sie können ein Byte sparen, indem Sie das Leerzeichen zwischen x<4undor
acrolith
In Python 2 können Sie das f(x-1.)Casting verwenden , um zu schweben. In Python 3 müssen Sie überhaupt nicht umsetzen.
Dennis
5

Haskel, 32 Bytes

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

Anwendungsbeispiel: ((0#1)1!!) 7-> 2.642857142857143. Ich starte die folge mit 0, 1, 1fix!! der 0-basierten Indizierung.

Bearbeiten: @xnor hat eine Möglichkeit gefunden, von einem 0-basierten zu einem 1-basierten Index zu wechseln, ohne die Byteanzahl zu ändern.

nimi
quelle
1
Gute Methode, um die direkte rekursive Definition zu schlagen. Ich denke, Sie können durch Initialisieren zu 1-indiziert wechseln (0,1,1).
xnor
4

Ruby, 34 Bytes

Da Ruby standardmäßig die Ganzzahldivision verwendet, stellt sich heraus, dass es kürzer ist, stattdessen Brüche zu verwenden. Golfvorschläge sind willkommen.

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

Perl 6 ,  25  23 Bytes

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

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

Erläuterung:

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

Dies gibt eine Rat ( Rational ) für Eingaben zurück, die mit 3 beginnen, bis das Ergebnis einen Nenner aufweist, der größer ist als eine 64-Bit-Ganzzahl und an diesem Punkt Num s (Gleitkomma) zurückgibt .
Die letzte Ratte, die es zurückgibt, istP(11) == 8832072277617 / 2586200337022

Wenn Sie möchten, dass Rational- Zahlen anstelle von Floats zurückgegeben werden, können Sie sie gegen die folgenden austauschen, wodurch stattdessen eine FatRat zurückgegeben wird.

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

Prüfung:

#! /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
quelle
3

C 46 Bytes

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

Ideone

betseg
quelle
3

MATL , 15 Bytes

llli3-:"3$t/+]&

Probieren Sie es online!

Erläuterung

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
quelle
2

Cheddar , 31 Bytes

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

Die ungolfed Version ist so klar, dass Sie keine Erklärung brauchen:

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

Grundsätzlich können Sie nach den Funktionsargumenten die zu verwendende Variable angeben, die für die Funktion selbst festgelegt wird. Warum? denn diese funktion wird tail-call-optimiert oder sollte es zumindest sein.

Downgoat
quelle
2

Javascript (ES6), 31 Byte

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

Eine einfache Funktion.

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-Zerfall
quelle
Warum nicht ES6? Das spart eine Tonne Bytes.
Ismael Miguel
So:P=n=>n<4?1:P(n-3)+P(n-2)/P(n-1)
Ismael Miguel
@IsmaelMiguel Danke. Ehrlich gesagt habe ich keine Ahnung, wie sich die verschiedenen Javascripts unterscheiden: D
Beta Decay
Zu Ihrem Vorteil müssen Sie bei den meisten Herausforderungen nur die "Big Arrow Notation" kennen, mit der Sie Funktionen erstellen können, ohne das Schlüsselwort zu verwenden function. Das Bit P=n=>[...]erstellt eine anonyme Funktion, die 1 Parameter (n) akzeptiert. Auf ES6 sind Rückgaben ebenfalls implizit. Ist P=n=>5also eine Funktion, die immer zurückkehrt 5. Sie müssen den Body nur einschließen, {}wenn Sie mehr als eine Anweisung haben (zB:) P=n=>{alert(1);console.log(1)}. Da Sie nur 1 (große) Anweisung (den ternären Operator) haben, können Sie den vergessen {}.
Ismael Miguel
@IsmaelMiguel Danke, das wird nützlich sein: D
Beta Decay
2

05AB1E , 18 17 Bytes

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

Probieren Sie es online!

1 Byte dank Luis Mendo gespeichert

Emigna
quelle
1

Gelee , 15 Bytes

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

Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

ạ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
quelle
1

R 53 47 Bytes

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

Diese Antwort machte Gebrauch von der hübschen, ordentlichen Funktion ifelse:ifelse(Condition, WhatToDoIfTrue, WhatToDoIfNot)

Frédéric
quelle
1
Sie sollten in der Lage sein, das return()in Ihrem Code loszuwerden . Sie müssen die Funktion aber auch benennen, damit Ihre Rekursion funktioniert
user5957401
0

Mathematica, 36 Bytes

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

Hier sind die ersten Begriffe:

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

Dyalog APL, 25 Bytes

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

ngn
quelle