Fibonacci alternati


17

Nella sequenza alternata di Fibonacci, inizi prima con 1e 1come al solito.

Tuttavia, invece di aggiungere sempre gli ultimi due valori per ottenere il numero successivo, si alternano a partire dall'aggiunta e ogni altra volta invece si sottrae.

La sequenza inizia in questo modo:

1
1
2    # 1 + 1
-1   # 1 - 2
1    # 2 + -1
-2   # -1 - 1
-1   # 1 + -2
-1   # -2 - -1
-2   # -1 + -1
1    # -1 - -2
-1   # -2 + 1
2    # 1 - -1
1    # -1 + 2
1    # 2 - 1

eccetera.

Si noti che dopo che ricomincia una volta, si arriva 1e si 1ripete.

Dato un numero N , stampare il N esimo termine della sequenza alternata di Fibonacci.

Ricorda, questo è , quindi vince il codice con il minor numero di byte.


La sequenza è 0-indicizzata o 1-indicizzata (o una delle due)?
Maniglia della porta

@Doorknob Uno dei due. Specifica nella tua risposta.
Oliver Ni

Possiamo tornare trueper 1?
ETHproductions

I primi due 1valori contano come valori iniziali per l'output? O iniziamo direttamente con 2?
Luis Mendo,

@LuisMendo I primi due contano.
Oliver Ni,

Risposte:


17

JavaScript (ES6), 25 byte

n=>"334130110314"[n%12]-2

0-indicizzati. Puoi abbreviare la stringa con una versione leggermente ricorsiva, sebbene aggiunga 6 byte:

f=n=>"3341301"[n]-2||f(13-n%12)

Questo è ancora più breve della formula ricorsiva definitiva:

f=n=>n<2||f(n-2)+f(n-1)*(-n%2|1)

8

Python, 31 byte

lambda n:2-33107256/5**(n%12)%5

Non si preoccupa di provare a calcolare il valore. Cerca nella lista peroidica lunghezza-12 [1, 1, 2, -1, 1, -2, -1, -1, -2, 1, -1, 2], che è compressa nella base 5.

Confronta con una soluzione ricorsiva (37 byte) con True's per 1:

f=lambda n:n<2or(-1)**n*f(n-1)+f(n-2)

o per archiviare le stringhe

lambda n:int('334130110314'[n%12])-2

o un tentativo di espressione aritmetica.

lambda n:4**n%7%3*(-1)**((n+n%2*4)/6)

7

Oasi , 10 byte

Mi ricorda di implementare altri built-in: p. L'input è indicizzato 0 .

Codice:

n>2%x<*c+V

Versione tradotta:

a(n) = (2*((n+1)%2)-1) * a(n-1) + a(n-2)
a(1) = 1
a(0) = 1

E calcola il n esimo termine.

Provalo online!




4

Gelatina, 12 byte

“½Ġ⁻S’b5_2⁸ị

TryItOnline!

In base 1, dato il primo e il secondo valore sono 1.

Non sono sicuro se questo è ancora più breve, ma per questo ho notato che la serie ha un periodo di 12:
[1, 1, 2, -1, 1, -2, -1, -1, -2, 1, -1, 2]

Quindi, l'ho preso e aggiunto 2per dare
[3, 3, 4, 1, 3, 0, 1, 1, 0, 3, 1, 4]
poi convertito come 5numero base in base 250, per dare:
[11, 197, 140, 84]
(che è 184222584).

“½Ġ⁻S’b5_2⁸ị - Main link: n
“½Ġ⁻S’       - base 250 number      184222584
      b5     - convert to base 5   [3, 3, 4, 1, 3, 0, 1, 1, 0, 3, 1, 4]
        _2   - subtract 2          [1, 1, 2, -1, 1, -2, -1, -1, -2, 1, -1, 2]
          ⁸  - left argument, n
           ị - index into (1-based and modular)

4

Haskell, 33 26 byte

a!b=a:b:(a+b)!(-a)
(1!1!!)

Approccio ricorsivo 0-indicizzati. Provalo su Ideone.
Salvato 7 byte grazie a xnor .

Uso:

Prelude> (1!1!!)11
2

Sembra più breve da fare a!b=a:b:(a+b)!(-a).
xnor

3

Mathematica, 40 byte

Crea semplicemente una tabella di ricerca e accede ciclicamente, come nella risposta di ETHproductions. Funzione senza nome, 1 indicizzata.

Join[s={2,1,1,2,-1,1},-s][[#~Mod~12+1]]&

3

MATL , 17 16 15 byte

'"Bl)e'F5Za2-i)

L'input è basato su 1.

Provalo online!

Spiegazione

La sequenza ha punto [1 1 2 -1 1 -2 -1 -1 -2 1 -1 2].

'"Bl)e     % Compressed array [1 1 2 -1 1 -2 -1 -1 -2 1 -1 2] with source 
           % alphabet [-2 -1 0 1 2]
F5Za       % Decompress with target alphabet [0 1 2 3 4]
2-         % Subtract 2 to transform alphabet into [-2 -1 0 1 2]
i)         % Input N and use as (modular, 1-based) index into the sequence

3

WinDbg, 26 byte

?(85824331b>>@$t0%c*3&7)-2

L'input viene passato attraverso lo pseudo-registro $t0. 0-indicizzati. +2 di ciascun termine nella sequenza è memorizzato in 3 bit85824331b .

Come funziona:

? (85824331b >> @$t0 % c * 3 & 7) - 2 ;*? Evalutes the expression. Shifts 85824331b to get
                                       *the 3 bits for the @$t0'th term (mod c (12) when
                                       *the sequence repeats). Bitwise AND by 7 to get the
                                       *desired 3 bits, finally subtract 2 since the terms
                                       *where stored as +2.

Esempio di output, un ciclo che stampa i primi 14 valori della sequenza:

0:000> .for(r$t0=0;@$t0<e;r$t0=@$t0+1){?(85824331b>>@$t0%c*3&7)-2}
Evaluate expression: 1 = 00000001
Evaluate expression: 1 = 00000001
Evaluate expression: 2 = 00000002
Evaluate expression: -1 = ffffffff
Evaluate expression: 1 = 00000001
Evaluate expression: -2 = fffffffe
Evaluate expression: -1 = ffffffff
Evaluate expression: -1 = ffffffff
Evaluate expression: -2 = fffffffe
Evaluate expression: 1 = 00000001
Evaluate expression: -1 = ffffffff
Evaluate expression: 2 = 00000002
Evaluate expression: 1 = 00000001
Evaluate expression: 1 = 00000001

3

Java, 32 byte

n->"334130110314".charAt(n%12)-50

Poiché si tratta di Java, la risposta è indicizzata 0.

Test e non golfato:

class Ideone {
  public static void main (String[] args) throws Exception {
    java.util.function.IntFunction f = n->"334130110314".charAt(n%12)-50;
    for (int i = 0; i < 12; i++) {
      System.out.printf("%d -> %d%n", i, f.apply(i));
    }
  }
}

Test su Ideone


2

Mathematica, 45 41 38 byte

Grazie a @MartinEnder per 3 byte.

±0=±1=1;±n_:=±(n-2)+±(n-1)(1-2n~Mod~2)

0-indicizzati.

uso

±5

-2


2
Probabilmente puoi salvare tre byte definendo un operatore unario ±invece di una funzione a.
Martin Ender,

1

Perl 6 ,  39 35  32 byte

{(1,1,{|(($/=$^a+$^b),$b-$/)}...*)[$_]}
{(|(334130110314.comb X-2)xx*)[$_]}
{(|334130110314.comb xx*)[$_]-2}
{334130110314.substr($_%12,1)-2}

1

C #, 117 byte

golfed:

int A(int n){var f=new List<int>{0,1,1};for(int i=3;i<=n;i++){f.Add(i%2>0?f[i-1]+f[i-2]:f[i-2]-f[i-1]);}return f[n];}

Ungolfed:

public int A(int n)
{
  var f = new List<int> { 0, 1, 1 };

  for (int i = 3; i <= n; i++)
  {
    f.Add(i % 2 > 0 ? f[i - 1] + f[i - 2] : f[i - 2] - f[i - 1]);
  }

  return f[n];
}

test:

var alternatingFibonacci = new AlternatingFibonacci();
Console.WriteLine(alternatingFibonacci.B(10));
1

Compilare in Func <int, int> così public int A(int n)è ora n=>, è possibile rimuovere le parentesi graffe attorno all'istruzione for salvando 2 byte, è possibile pre-incrementare iil ciclo nel ie ie ++i <= nimpostare il i = 2salvataggio di 3 byte perché rimuove il i++alla fine dell'istruzione
TheLethalCoder

Vedi anche la mia risposta se hai tenuto traccia delle variabili precedenti invece di creare un elenco di tutte, è molto più breve
TheLethalCoder

1

R, 38 byte

Utilizza la soluzione di tabella di ricerca ispirata alla risposta JS di @ETHproductions.

c(s<-c(2,1,1,2,-1,1),-s)[scan()%%12+1]

Modifica: ho dimenticato di dire che questo è 1-indicizzato.


1

In realtà , 22 byte

34*@%"334130110314"E≈¬

Provalo online!

Spiegazione:

34*@%"334130110314"E≈¬
34*@%                   input % 12
     "334130110314"E    get that character in the string
                    ≈¬  convert to int, subtract 2

1

Java 7, 88 82 79 byte

golfed:

int f(int n){int c,i=0,a=1,b=1;for(;i<n;){c=i++%2>0?a-b:a+b;a=b;b=c;}return b;}

ungolfed:

int f(int n)
{
    int c, i = 0, a = 1, b = 1;
    for (; i < n;)
    {
        c = i++ % 2 > 0 ? a - b : a + b;
        a = b;
        b = c;
    }
    return b;
}

Provalo online


1
Dato che segui la strada "logica", ecco alcuni suggerimenti: 1. hai dimenticato di dichiarare intcome tipo di ritorno. 2. è possibile risparmiare byte spostando l'assegnazione di 0 nella dichiarazione di i: int c,i=0e for(;i<n;){. 3. È possibile rimuovere la parentesi attorno alle condizioni dell'operatore ternario.
Olivier Grégoire,

1
@ OlivierGrégoire grazie amico :) risolto. bella soluzione tra
peech

1

DC, 55 byte

?sd[ln1+snly[[+2Q]sEln2%1=E-]xlyrsylnld>r]sr1sy0sn1lrxp

0-indicizzati.

?sd                                                     takes input and stores
                                                        it in register d

                                            1sy0sn1     stores 1 in register y
                                                        and 0 in register n and
                                                        appends 1 to the stack

   [ln1+snly                                            adds 1 to register n and
                                                        appends the value of
                                                        register y to the stack

            [[+2Q]sEln2%1=E-]                           adds or subtracts the
                                                        the two values on the
                                                        stack depending on
                                                        parity of n

                             xlyrsylnld>r]              does the rest of the
                                                        stuff required to store
                                                        the new values properly
                                                        and quits if it has
                                                        done enough iterations

                                          sr            stores the main macro
                                                        in register r

                                                   lrxp executes the macro and
                                                        prints the stack

Il registro d memorizza l'indice del valore. Il registro n conta il numero di iterazioni completate. Register r memorizza la macro principale. Register y memorizza il valore successivo nella sequenza, mentre lo stack contiene il valore precedente nella sequenza.

Spiegazione visiva di cosa sta succedendo nel big loop (supponendo l'aggiunta):

register: y=1     y=1   y=1    y=1   y=1    y=2
stack:     1      1 1    2     2 1   1 2     1
               ly     +     ly     r     sy

Il controllo per determinare se aggiungere o sottrarre prende il contatore modulo due e lo utilizza questo trucco per creare una costruzione if then else.

Alla fine la pila contiene un singolo numero, il valore desiderato, che viene stampato con p .

(Sono nuovo dc, quindi mi aspetto che ci siano alcuni ovvi miglioramenti da apportare qui.)


0

ForceLang , 153 byte

def s set
s a 1
s b 1
s p 1
s k io.readnum()
if k=0
goto b
label a
s c b.mult p
s c a+c
s a b
s b c
s p p.mult -1
s k k+-1
if k
goto a
label b
io.write a

0

Turtlèd , 35 byte

#112-1_--_1-2#?:[*l+].(-r'1)(_"-2")

0 indicizzato

Spiegazione:

#112-1_--_1-2#                      the 12 values of sequence. - is -1, _ is -2
              ?:                    input a number and move right that many
                [*l+]               move back to the asterisk on start cell, 
                                    increment sting pointer by amount moved
                     .              write pointed char
                      (-r'1)        if it was -, move right, write 1
                            (_"-2") if it was _, write "-2"
      [print grid]

Provalo online!


0

ABCR, 43 byte

)AAB)ABB..A))A..A)AA(ABB.)A+A)))AiB5aAb(Bxo

Spiegazione: la prima parte ( )AAB)ABB..A))A..A)AA(ABB.)A+A)))A) imposta la coda A per contenere [1, 1, 2, -1, 1, -2, -1, -1, -2, 1, -1, 2], mantenendo vuote tutte le altre code . iBmemorizza il termine desiderato e il ciclo 5aAb(Bxscorre più volte la coda. ostampa la parte anteriore della coda come un numero, che sarà quindi la nostra risposta desiderata.


0

Lotto, 49 byte

@cmd/cset/a"n=%1%%12,~!(n%%3)*(1|-!(n%%5*(n/4)))"

Accetta l'input come parametro della riga di comando. Spiegazione: Il modulo chiuso utilizza le seguenti osservazioni:

  • La sequenza è ciclica con il periodo 12
  • Ogni terzo termine è ± 2 mentre gli altri termini sono ± 1
  • I termini dopo il terzo sono negativi tranne i multipli di 5 (dopo aver ridotto il modulo 12)

Iniziamo quindi riducendo il modulo 12 (per salvare 2 byte). Riduciamo quindi il modulo tre e invertiamo il risultato, che è 1 per multipli di 3 o 0 altrimenti. Quindi non bit per bit quel valore, dandoci -2 per multipli di 3 o -1 altrimenti. Riduciamo quindi il modulo 5 e dividiamo separatamente per 4, dando zero per i termini 1, 2, 3, 5, 10 e 12 (0). L'inversione e la negazione ci danno -1 per quei valori e zero per altri valori. Quindi bit a bit o quello con 1 e moltipliciamo per il calcolo precedente.


0

TI-Basic, 26 byte

Purtroppo, approccio molto poco interessante. Non sono riuscito a trovare niente di più corto. L'elenco è 1 indicizzato.

Input :{1,1,2,-1,1,-2:augment(Ans,-Ans:Ans(X

0

C #, 73 71 byte

Questo utilizza valori indicizzati 0 di n.

n=>{int a=1,b=1,i=0,r;for(;++i<n;){r=i%2>0?a+b:a-b;a=b;b=r;}return b;};

Versione formattata:

Func<int, int> f = n =>
{
    int a = 1, b = 1, i = 0, r;

    for(; ++i < n;)
    {
        r = i % 2 > 0 ? a + b : a - b;
        a = b;
        b = r;
    }

    return b;
};
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.