Sequenza di Stewie: + * - / + * - /


29

Usiamo le quattro operazioni di base, addizione +, moltiplicazione *, sottrazione -e divisione /(float, non intero).

La sequenza di Stewie è definita come segue:

x = [x(1), x(2)]    // Two initial numbers (one indexed)
x(3) = x(1) + x(2)
x(4) = x(2) * x(3)
x(5) = x(3) - x(4)
x(6) = x(4) / x(5)
x(7) = x(5) + x(6)
... and so on.

Sfida:

Prendi due numeri interi non negativi ( x(1), x(2)) e un numero intero positivo Ncome input.

x(1)e x(2)saranno i primi due numeri della sequenza e Nsarà la lunghezza della sequenza che devi generare. (Puoi scegliere di avere l'elenco basato su 0, nel qual caso Nsarà uno in meno della lunghezza).

  • Non puoi supporre che x(2) >= x(1).
  • Nsarà sempre >2se basato su 1 ( >1se basato su 0).
  • Non è necessario gestire la divisione per zero errori.
    • Nota il secondo caso di test. Non otterrai 0, 1, e N=6come input, poiché ciò comporterà una divisione per zero, ma devi supportare 0, 1e N=5.
  • Supponiamo che venga fornito solo un input valido.
  • L'input e l'output possono essere in qualsiasi formato conveniente, ma è necessario supportare almeno 3 cifre dopo i punti decimali se l'output è non intero.

Casi test:

1 3
8
1, 3, 4, 12, -8, -1.5, -9.5, 14.25

0 1
5
0, 1, 1, 1, 0     // N=6 would give division by zero error. You don't need to handle that case.

1 0
9
1, 0, 1, 0, 1, 0, 1, 0, 1

6 3
25
6, 3, 9, 27, -18, -1.5, -19.5, 29.25, -48.75, -0.6, -49.35, 29.61, -78.96, -0.375, -79.335, 29.7506, -109.086, -0.272727, -109.358, 29.825, -139.183, -0.214286, -139.398, 29.8709, -169.269

Una funzione può prendere x (1) e x (2) come elenco? O argomenti separati?
FlipTack,

Qualunque cosa ti sia conveniente :)
Stewie Griffin,

Può Nessere basato su 0? Quindi prendi come input 1 in meno della N mostrata nei tuoi esempi. Immagino che prendere N-2 sia troppo da chiedere ... :-P
Luis Mendo,

Quando scrivi l' output può essere in qualsiasi formato conveniente , include un elenco con l'elemento finale all'inizio e gli elementi start alla fine (un elenco invertito)?
Emigna,

1
@Emigna, no, penso che sia un po 'allungato ... I numeri dovrebbero essere nell'ordine corretto
Stewie Griffin,

Risposte:


3

MATL , 19 18 17 byte

q:"y'+*-/'@)hyhUV

Input è nel formato: N(0-based), x(1), x(2)(come stringhe); tutti separati da newline.

Provalo online! Oppure verifica tutti i casi di test (codice leggermente modificato; sequenze di output separate da una riga vuota).

Spiegazione

MATL non ha una evalfunzione appropriata , ma U( str2num) può valutare espressioni numeriche con operatori infix.

Ogni nuovo termine viene calcolato e inserito nello stack, mantenendo i termini precedenti. L'intera pila è stampata alla fine.

q          % Implicitly input N (0-based). Subtract 1
:"         % Repeat that many times
  y        %   Duplicate x(n-1), where n is the number of already computed terms
           %   In the first iteration, which corresponds to n=2, this implicitly 
           %   inputs x(1) and x(2) as strings (and then duplicates x(1))
  '+*-/'   %   Push this string
  @)       %   Push iteration number and apply as modular index into the string. 
           %   So this gives '+' in the first iteration, '*' in the second etc
  h        %   Concatenate horizontally. This gives a string of the form
           %   '*x(n-1)+', where '+' is the appropriate operator 
  &y       %   Duplicate x(n)
  hh       %   Concatenate horizontally. This gives a string of the form
           %   'x(n-1)+x(n)'
  U        %   Convert to number. This evaluates the string
  V        %   Convert back to string. This is the new term, x(n+1)
           % Implicitly end loop and display stack

7

Haskell, 69 68 64 byte

x#n=take n$x++zipWith3 id(cycle[(+),(*),(-),(/)])(x#n)(tail$x#n)

x1e x2sono presi come un elenco. Esempio di utilizzo: [1,3] # 8-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

La pigrizia rende possibile definire un infinito elenco ricorsivo in cui prendiamo i primi n elementi.

Haskell, 66 byte

(h%g)y x=x:g(h x y)y
a=(+)%b
b=(*)%c
c=(-)%d
d=(/)%a
(.a).(.).take 

Approccio diverso, leggermente più lungo. Ordine argomento è N, x2, x1. Esempio di utilizzo: ( (.a).(.).take ) 8 3 1-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

Definisce 4 funzioni a, b, ce dche prendono due argomenti y, x e fare una lista mettendo xdavanti a una chiamata alla funzione successiva con ycome secondo argomento e x op ycome il primo. Ad esempio aè: a y x = x : (b (x+y) y), bfa moltiplicazione: b y x = x : (c (x*y) y), etc.

Modifica: @Michael Klein ha salvato un byte nella prima variante ( #). Fortunatamente ho anche trovato un byte per la seconda variante, quindi entrambi hanno di nuovo la stessa lunghezza.

Modifica II: @Zgarb ha trovato 2 byte nella seconda versione da salvare, e I 4 nella prima, quindi non hanno più la stessa lunghezza.


Accetta gli argomenti come un elenco (consentito) per un byte
Michael Klein,

Mi confondo sempre se (.)è composto con altre funzioni: p
tomsmeding del

g x=(`take`f)wherenon salva un byte: - /
Bergi il

Salvare 2 byte nell'approccio alternativo:(h%g)y x=x:g(h x y)y
Zgarb,

@Zgarb: oh, è carino. Grazie! A proposito, durante la modifica dei tuoi suggerimenti ho trovato 4 byte da salvare lungo la strada nella prima versione.
nimi,

6

ES6 (Javascript), 79, 67, 65 byte

AGGIORNARE

  • meno 2 byte, iniziando con i = 2, come suggerito da @ETHProductions
  • Salvato 3 byte, grazie all'eccellente consiglio di @Neil!

golfed

S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"-/+*"[i%4]+a[i-1]))):a

Test

S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"-/+*"[i%4]+a[i-1]))):a

>S(8,[1,3])
Array [ 1, 3, 4, 12, -8, -1.5, -9.5, 14.25 ]

>S(5,[0,1])
Array [ 0, 1, 1, 1, 0 ]

>S(9,[1,0])
Array [ 1, 0, 1, 0, 1, 0, 1, 0, 1 ]

>S(25,[6,3])
Array [ 6, 3, 9, 27, -18, -1.5, -19.5, 29.25, -48.75, -0.6, ...]

1
Non puoi usare ++iper evitare di dover aggiungere 1 a idue?
Neil,

1
Oppure, in alternativa, la scrittura ?S(n,a,i+1,a.push(...)):apotrebbe farti risparmiare qualche byte.
Neil,

1
O forse potresti usare il fatto che a.pushrestituisce la nuova lunghezza,S=(n,a,i=2)=>i<n?S(n,a,a.push(...)):a
Neil,

1
Penso ancora che puoi salvare più byte iniziando da i=2però.
Neil,

1
Con il suggerimento di Neil, penso che tu possa fare S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"+*-/"[i%4]+a[i-1]))):aper salvare 2 byte.
ETHproductions

5

Python 3, 90 80 74 byte

xnor probabilmente verrà e distruggerà questa soluzione ...

def F(s,n,i=2):
 while i<n:s+=eval('%s'*3%(s[-2],'-/+*'[i%4],s[-1])),;i+=1

La funzione modifica l'elenco passato ad esso. Usa così:

s = [1,3] 
F(s,8)

Prova su repl.it!

-6 byte grazie a Copper


Dal momento che si utilizza Ouna sola volta, è possibile salvare alcuni byte eseguendo '-/+*'[i%4]e rimuovendo la dichiarazione di O. Inoltre, potresti essere in grado di aggirare le chiamate ripetute strfacendo qualcosa di simile eval('%s'*3%(s[-2],'-/+*'[i%4],s[-1])).
Rame

Oh sì, e s+=[...]può essere sostituito da s+=...,(notare la virgola finale).
Rame

xnor non è l'unico che può distruggere la tua soluzione. C'è anche un'altra persona: Dennis (il mod).
Erik the Outgolfer,

Hai la garanzia di ottenere icome input, quindi non è necessario il valore predefinito ( i=2può essere giusto i). Due byte in meno.
ArtOfCode

1
Se invece fosse permesso di restituire l' nelemento th nella sequenza, questo è più corto di 1 byte con ricorsione:f=lambda x,n:n<2and x[n-1]or eval('%s'*3%(f(x,n-2),'*-/+'[n%4],f(x,n-1)))
mbomb007

5

Perl 6 ,  75 71  61 byte

->\a,\b,\c{$_=[|(&[+],&[*],&[-],&[/])xx*];(a,b,{.shift.($^a,$^b)}...*)[^c]}

Provalo

{$_=[|(&[+],&[*],&[-],&[/])xx*];($^a,$^b,{.shift.($^a,$^b)}...*)[^$^c]}

Provalo

{($^a,$^b,{(&[+],&[*],&[-],&[/])[$++%4]($^a,$^b)}...*)[^$^c]}

Provalo

Allargato:

{ # bare block lambda with placeholder parameters 「$a」 「$b」 「$c」

  # generate sequence
  (
    # initialize sequence
    $^a, # declare and use first argument
    $^b, # second argument

    {  # bare block lambda with two placeholder parameters 「$a」 「$b」

      (

        &[+], &[*], &[-], &[/] # the four operators

      )[             # index into the list of operators

         $++        # increment (++) an anonymous state variable ($)
         % 4        # modulo 4

      ]( $^a, $^b ) # and use it on the previous two values in sequence

    }

    ...  # repeat that until

    *    # indefinitely

  )[     # take only

    ^    # upto and excluding:     ( Range object )
    $^c  # third argument

  ]
}

4

Mathematica, 68 byte

(±1=#;±2=#2;±n_:=1##[#-#2,#/#2,+##][[n~Mod~4]]&[±(n-2),±(n-1)];±#3)&

Appena arrivato al 3 ° posto! Funzione senza nome di tre argomenti, che utilizza un operatore unario helper ±tale che ±nè esattamente l'ennesimo elemento x (n) della sequenza di Stewie. I primi due argomenti sono x (1) e x (2), e il terzo argomento è la N che indica quale x (N) abbiamo prodotto.

Implementazione diretta, usando un calcolo mod-4 per scegliere quale funzione binaria applicare ai due termini precedenti. Scegliere la corretta funzione binaria, che è ciò che 1##[#-#2,#/#2,+##]aiuta, utilizza alcuni di questi trucchi di golf Mathematica divertenti .


3

05AB1E , 21 19 18 byte

L'input viene preso nell'ordine N (basato su 0), x (2) , x (1) .
Salvato 1 byte grazie al carusocomputing .

GUDXsX"/+*-"Nè.V})

Provalo online!

Spiegazione

 G                   # for N in [0 ... n-1] do:
  U                  # save top element of stack in X
   D                 # duplicate top of stack
    X                # push X
     s               # swap top 2 elements on stack
      X              # push X
       "/+*-"Nè      # index into the string with the current iteration number
               .V    # evaluate
                 }   # end loop
                  )  # wrap stack in list

Costruiamo iterativamente lo stack con l'ultimo elemento della sequenza in cima, mantenendo tutti gli elementi precedenti in ordine.
Quindi avvolgiamo lo stack in un elenco alla fine per visualizzare tutti i valori contemporaneamente.


1
Non sono riuscito a capirlo, ma usando XYe potrei UVsalvarti byte.
Magic Octopus Urn,

1
@carusocomputing: bella cattura! Ho salvato il byte perso dal registro non funzionando sull'input implicito usando UX:)
Emigna,

2

Lisp comune, 158

(lambda(x y n)(loop repeat n for a = x then b for b = y then r for o in '#1=(+ * - / . #1#)for r =(ignore-errors(funcall o a b))collect(coerce a'long-float)))

Non proprio competitivo, ma mi piace come è espresso in modo abbastanza naturale:

(lambda (x y n)
  (loop 
    repeat n
    for a = x then b
    for b = y then r
    for o in '#1=(+ * - / . #1#)
    for r = (ignore-errors (funcall o a b))
    collect (coerce a 'long-float)))

Ignoriamo gli errori durante il calcolo di R, il che rende probabilmente R (e quindi B) il valore NIL. Ciò consente di produrre il risultato corrente anche se il valore successivo non è definito. Quindi, alla fine il ciclo fallirà, ma è all'interno delle regole.

test

Chiamiamo la funzione Fe verifichiamo che i valori previsti siano approssimativamente uguali a quello testato.

(loop
  for (args expected)
    in
  '(((1 3 8)
     (1 3 4 12 -8 -1.5 -9.5 14.25))

    ((0 1 5)
     (0 1 1 1 0))

    ((1 0 9)
     (1 0 1 0 1 0 1 0 1))

    ((6 3 25)
     (6 3 9 27 -18 -1.5 -19.5 29.25 -48.75 -0.6 -49.35 29.61 -78.96 -0.375 -79.335 29.7506 -109.086 -0.272727 -109.358 29.825 -139.183 -0.214286 -139.398 29.8709 -169.269)))

  for result = (apply #'f args)
  always (every (lambda (u v) (< (abs (- u v)) 0.001)) result expected))

=> T

Il motivo del test approssimativo è perché i valori calcolati sono un po 'più precisi del necessario; qui, per (f 6 3 25):

(6.0d0 3.0d0 9.0d0 27.0d0 -18.0d0 -1.5d0 -19.5d0 29.25d0 -48.75d0 -0.6d0
 -49.35d0 29.61d0 -78.96d0 -0.375d0 -79.335d0 29.750625d0 -109.085625d0
 -0.2727272727272727d0 -109.35835227272727d0 29.825005165289255d0
 -139.18335743801654d0 -0.21428571428571427d0 -139.39764315230224d0
 29.870923532636194d0 -169.26856668493843d0)

2

dc, 112 110 108 byte

5k?sarfsmsn[pSnla1-Sa]sh[lmlndSm]sv[lvx/lhx]sb[lvx+lhx]sc[lvx*lhx]sd[lvx-lhx]se[lcx2la>d2la>e2la>b2la>j]dsjx

A volte le dcrisposte possono essere molto lunghe, a volte possono essere molto brevi. Tutto dipende solo dalla sfida a portata di mano, come nel caso di molte altre lingue. Ad ogni modo, questo richiede un input a riga di comando a un indice separato da spazio di 3 numeri interi, x(1), x(2), Nsu invocazione, e genera ogni elemento della sequenza su linee separate con output non interi che contengono 5 cifre dopo il punto decimale.

Ad esempio, l'input 6 3 25produce il seguente output:

6
3
9
27
-18
-1.50000
-19.50000
29.25000
-48.75000
-.60000
-49.35000
29.61000
-78.96000
-.37500
-79.33500
29.75062
-109.08562
-.27272
-109.35834
29.82420
-139.18254
-.21428
-139.39682
29.86995
-169.26677

2

Perl, 62 + 3 ( -plaflag) = 65 byte

push@F,eval$F[-2].qw(* - / +)[$_%4].$F[-1]for 3..pop@F;$_="@F"

usando:

perl -plae 'push@F,eval$F[-2].qw(* - / +)[$_%4].$F[-1]for 3..pop@F;$_="@F"' <<< '1 3 8'

1

Rubino, 79 byte

->(b,c,d){a=[b,c];(d-2).times{|i|a<<a[i].send(%i{+ * - /}[i%4],a[i+1]).to_f};a}

Sospetto che questo sia molto lontano dall'ottimale (e non ho ancora guardato le altre risposte), ma è comunque divertente.

Volevo divertirmi un po ' Enumerable#cycle, ma purtroppo sono solo 4 i personaggi in meno da usare %4.


1

C ++ 14, 118 byte

[](auto&v,int N){for(int i=0;++i<N-1;){auto p=v.rbegin(),q=p+1;v.push_back(i%4?i%4<2?*q+*p:i%4<3?*q**p:*q-*p:*q/ *p);}

Come lambda senza nome che modifica il suo input. Richiede vdi essere un vector<double>o vector<float>.

Ungolfed e utilizzo:

#include<iostream>
#include<vector>

auto f=
[](auto&v,int N){
  for(int i=0; ++i<N-1;){
    auto p=v.rbegin(),q=p+1;
    v.push_back(
      i%4 ?
        i%4<2 ? *q+*p : 
          i%4<3 ? *q**p : *q-*p
      : *q/ *p
    );
  }
};

int main(){
  std::vector<double> v={1,3};
  f(v,8);
  for (auto x:v) std::cout << x << ", ";
  std::cout << "\n";
}

1

codice macchina x86-64, 34 byte

Calling convention = x86-64 System V x32 ABI (registro args con puntatori a 32 bit in modalità lunga).

La firma della funzione è void stewie_x87_1reg(float *seq_buf, unsigned Nterms);. La funzione riceve i valori seed x0 e x1 nei primi due elementi dell'array e estende la sequenza fino ad almeno N più elementi. Il buffer deve essere arrotondato a 2 + N-arrotondato per eccesso al multiplo successivo di 4. (ovvero 2 + ((N+3)&~3), o solo N + 5).

Richiedere buffer imbottiti è normale nell'assemblaggio per funzioni ad alte prestazioni o con vettorializzazione SIMD, e questo ciclo srotolato è simile, quindi non credo che stia piegando troppo le regole. Il chiamante può facilmente (e dovrebbe) ignorare tutti gli elementi di riempimento.

Passare x0 e x1 come una funzione arg non già nel buffer ci costerebbe solo 3 byte (per a movlps [rdi], xmm0o movups [rdi], xmm0), anche se questa sarebbe una convenzione di chiamata non standard poiché System V passa struct{ float x,y; };in due registri XMM separati.

Questo viene objdump -drw -Mintelgenerato con un po 'di formattazione per aggiungere commenti

0000000000000100 <stewie_x87_1reg>:
       ;; load inside the loop to match FSTP at the end of every iteration
       ;; x[i-1] is always in ST0
       ;; x[i-2] is re-loaded from memory
 100:   d9 47 04                fld    DWORD PTR [rdi+0x4]
 103:   d8 07                   fadd   DWORD PTR [rdi]
 105:   d9 57 08                fst    DWORD PTR [rdi+0x8]
 108:   83 c7 10                add    edi,0x10            ; 32-bit pointers save a REX prefix here

 10b:   d8 4f f4                fmul   DWORD PTR [rdi-0xc]
 10e:   d9 57 fc                fst    DWORD PTR [rdi-0x4]

 111:   d8 6f f8                fsubr  DWORD PTR [rdi-0x8]
 114:   d9 17                   fst    DWORD PTR [rdi]

 116:   d8 7f fc                fdivr  DWORD PTR [rdi-0x4]
 119:   d9 5f 04                fstp   DWORD PTR [rdi+0x4]

 11c:   83 ee 04                sub    esi,0x4
 11f:   7f df                   jg     100 <stewie_x87_1reg>
 121:   c3                      ret    

0000000000000122 <stewie_x87_1reg.end>:
## 0x22 = 34 bytes

Questa implementazione di riferimento C si compila (con gcc -Os) in un codice un po 'simile. gcc sceglie la stessa strategia che ho fatto, di mantenere solo un valore precedente in un registro.

void stewie_ref(float *seq, unsigned Nterms)
{
    for(unsigned i = 2 ; i<Nterms ; ) {
        seq[i] = seq[i-2] + seq[i-1];       i++;
        seq[i] = seq[i-2] * seq[i-1];       i++;
        seq[i] = seq[i-2] - seq[i-1];       i++;
        seq[i] = seq[i-2] / seq[i-1];       i++;
    }
}

Ho sperimentato altri modi, tra cui una versione x87 a due registri con codice simile a:

; part of loop body from untested 2-register version.  faster but slightly larger :/
; x87 FPU register stack    ;       x1, x2   (1-based notation)
fadd    st0, st1            ; x87 = x3, x2
fst     dword [rdi+8 - 16]  ; x87 = x3, x2

fmul    st1, st0            ; x87 = x3, x4
fld     st1                 ; x87 = x4, x3, x4
fstp    dword [rdi+12 - 16] ; x87 = x3, x4
; and similar for the fsubr and fdivr, needing one fld st1

Lo faresti in questo modo se stavi andando per la velocità (e SSE non era disponibile)

Mettere i carichi dalla memoria all'interno del loop invece che una volta all'entrata potrebbe essere d'aiuto, dal momento che potremmo semplicemente salvare i risultati sub e div in ordine, ma ci vogliono ancora due istruzioni FLD per impostare lo stack all'entrata.

Ho anche provato a usare la matematica scalare SSE / AVX (a partire dai valori in xmm0 e xmm1), ma la dimensione dell'istruzione maggiore è killer. L'uso addps(dato che è 1B più corto di addss) aiuta un pochino. Ho usato i prefissi VEX di AVX per istruzioni non commutative, poiché VSUBSS è solo un byte più lungo di SUBPS (e della stessa lunghezza di SUBSS).

; untested.  Bigger than x87 version, and can spuriously raise FP exceptions from garbage in high elements
addps   xmm0, xmm1      ; x3
movups  [rdi+8 - 16], xmm0
mulps   xmm1, xmm0      ; xmm1 = x4,  xmm0 = x3
movups  [rdi+12 - 16], xmm1
vsubss  xmm0, xmm1, xmm0      ; not commutative.  Could use a value from memory
movups  [rdi+16 - 16], xmm0
vdivss  xmm1, xmm0, xmm1      ; not commutative
movups  [rdi+20 - 16], xmm1

Testato con questo cablaggio di prova:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

int main(int argc, char**argv)
{
    unsigned seqlen = 100;
    if (argc>1)
        seqlen = atoi(argv[1]);
    float first = 1.0f, second = 2.1f;
    if (argc>2)
        first = atof(argv[2]);
    if (argc>3)
        second = atof(argv[3]);

    float *seqbuf = malloc(seqlen+8);  // not on the stack, needs to be in the low32
    seqbuf[0] = first;
    seqbuf[1] = second;

    for(unsigned i=seqlen ; i<seqlen+8; ++i)
        seqbuf[i] = NAN;

    stewie_x87_1reg(seqbuf, seqlen);
//  stewie_ref(seqbuf, seqlen);
    for (unsigned i=0 ; i< (2 + ((seqlen+3)&~3) + 4) ; i++) {
        printf("%4d: %g\n", i, seqbuf[i]);
    }

    return 0;
}

Compila con nasm -felfx32 -Worphan-labels -gdwarf2 golf-stewie-sequence.asm &&
gcc -mx32 -o stewie -Og -g golf-stewie-sequence.c golf-stewie-sequence.o

Esegui il primo test-case con ./stewie 8 1 3

Se non hai installato le librerie x32, usa nasm -felf64e lascia gcc usando il valore predefinito -m64. Ho usato mallocinvece float seqbuf[seqlen+8](sullo stack) per ottenere un indirizzo basso senza dover effettivamente costruire come x32.


Curiosità: YASM ha un bug: usa un rel32 jcc per il ramo del ciclo, quando la destinazione del ramo ha lo stesso indirizzo di un simbolo globale.

global stewie_x87_1reg
stewie_x87_1reg:
   ;; ended up moving all prologue code into the loop, so there's nothing here
.loop:

...
sub    esi, 4
jg     .loop

assembla per ... 11f: 0f 8f db ff ff ff jg 100 <stewie_x87_1reg>




0

Bash, 224 byte (NO CONTEST)

Un'implementazione tremendamente ampia in BASH .

Prende il compito abbastanza letteralmente e fa tutto in un unico tubo continuo, senza strutture di flusso di controllo o ricorsioni empie.

Ingresso

$ 1, $ 2 - elementi iniziali

$ 3 - dimensione della sequenza target

golfed

{ echo "a[0]=$1;a[1]=$2;a[0];a[1]";paste <() <(seq 2 $[$3-1]) <(seq 0 $[$3-3]) <(printf '%.0s+*-/' `seq $[$3/4]`|fold -1|head -$[$3-2]) <(seq 1 $[$3-2]);}|sed -r '1 ! s/(.+)\s(.+)\s(.+)\s(.)/a[\1]=a[\2]\3a[\4];a[\1];/'|bc -l

Meno golfato

{ 
 echo "a[0]=$1;a[1]=$2;a[0];a[1]";
 paste <() <(seq 2 $[$3-1]) <(seq 0 $[$3-3]) <(printf '%.0s+*-/' `seq $[$3/4]`|fold -1|head -$[$3-2]) <(seq 1 $[$3-2]);
}\
|sed -r '1 ! s/(.+)\s(.+)\s(.+)\s(.)/a[\1]=a[\2]\3a[\4];a[\1];/' \
|bc -l

Test

>./stewie.sh 1 3 8
1
3
4
12
-8
-1.50000000000000000000
-9.50000000000000000000
14.25000000000000000000

Fasi della pipeline

Genera una tabella di indici degli elementi + op, per ciascun elemento della sequenza di output (uno per riga):

...
2   0   +   1
3   1   *   2
4   2   -   3
5   3   /   4
6   4   +   5
7   5   *   6
...

Usa sed per convertirlo in un programma bc lineare :

...
a[2]=a[0]+a[1];a[2];
a[3]=a[1]*a[2];a[3];
a[4]=a[2]-a[3];a[4];
a[5]=a[3]/a[4];a[5];
a[6]=a[4]+a[5];a[6];
a[7]=a[5]*a[6];a[7];
...

dai da mangiare a bc e lascia che faccia tutto il lavoro


0

Pyth - 20 byte

Produrre tutto nmi costa.

u+Gvj@"+*-/"H>2GttEQ

Non funziona online perché di eval.


0

Ceylon, 195 byte

Float[]s(Integer a,Integer b,Integer n)=>loop([a.float,b.float,[Float.divided,Float.plus,Float.times,Float.minus].cycled.rest])(([x,y,o])=>[y,(o.first else nothing)(x)(y),o.rest]).take(n)*.first;

Formattato e commentato:

// Print the first n entries of the Stewies sequence with given starting entries.
//
// Question:  http://codegolf.stackexchange.com/q/101145/2338
// My answer: http://codegolf.stackexchange.com/a/101251/2338

// Declare a function `s` which takes three integers, and returns a tuple
// of floats. (The more common syntax for the return value is [Float*],
// but Float[] is shorter.)
Float[] s(Integer a, Integer b, Integer n)
       // it is implemented by evaluating the following expression for each call.
         =>
        // start a loop with ...
        loop([
              // ... float versions of the integers, and ...
              a.float, b.float,
              // ... an infinite sequence of the four operators, ever repeating.
              // I needed the `.rest` here so the whole thing gets a {...*} type
              // instead of {...+}, which doesn't fit to what o.rest returns.
              // Each operator has the type Float(Float)(Float), i.e. you apply
              // it twice to one float each to get a Float result.
              [Float.divided, Float.plus, Float.times, Float.minus].cycled.rest])
               // in each iteration of the loop, map the triple of two numbers
               // and a sequence of operators to a triple of ... 
            (([x, y, o]) => [
               // the second number, 
                y,
               //the result of the first operator with both numbers
               // (using this "else nothing" here to convince the
               //  compiler that o.first is not null),
                   (o.first else nothing)(x)(y),
               // and the sequence of operators without its first element.
               // (that one unfortunately has a {...*} type, i.e. a possibly
               //  empty sequence.)
                                                 o.rest])
            // now we got an infinite sequence of those triples.
            // We just want the first n of them ...
                .take(n)
            // and of each triple just the first element.
            // (The *. syntax produces a tuple, non-lazily.
            //  We could also have used .map((z) => z.first)
            //  or .map(Iterable.first) or .map((z) => z[0]), each of
            //  which would return a (lazy) sequence, but they all would be
            //  longer.)
                *.first;

Esempio di utilizzo:

shared void run() {
    print(s(1, 3, 8));
    print(s(0,1,11));
    print(s(1,0,9));
    print(s(6, 3, 29));
}

Esempio di output:

[1.0, 3.0, 4.0, 12.0, -8.0, -1.5, -9.5, 14.25]
[0.0, 1.0, 1.0, 1.0, 0.0, Infinity, Infinity, Infinity, NaN, NaN, NaN]
[1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0]
[6.0, 3.0, 9.0, 27.0, -18.0, -1.5, -19.5, 29.25, -48.75, -0.6, -49.35, 29.61, -78.96000000000001, -0.37499999999999994, -79.33500000000001, 29.750625, -109.08562500000001, -0.2727272727272727, -109.35835227272727, 29.825005165289255, -139.18335743801651, -0.2142857142857143, -139.39764315230224, 29.870923532636194, -169.26856668493843, -0.17647058823529413, -169.44503727317374, 29.90206540114831, -199.34710267432206]

Il secondo esempio mostra come gestire la divisione per zero. L'ultimo esempio mostra che i risultati si discostano un po 'a seconda del tipo di aritmetica (e arrotondamento) che si sta usando ... Penso che l'aritmetica a virgola mobile a 64 bit di Ceylon sia un po' più vicina a ciò che dovrebbe essere rispetto a ciò che è stato pubblicato nella domanda .


0

Clojure, 99 byte

#(let[ops[+ * - /]](take %3(map first(iterate(fn[[a b i]][b((ops i)a b)(mod(inc i)4)])[%1 %2 0]))))

Questa versione è più pratica da usare in pratica ma ha 110 byte:

(defn f[a b n](let[ops[+ * - /]](take n(map first(iterate(fn[[a b i]][b((ops i)a b)(mod(inc i)4)])[a b 0])))))

Ho avuto problemi a alimentare la funzione iterata e una sequenza ciclica di operazioni, quindi ho dovuto usare un contatore. Ho anche provato a utilizzare una tabella di transizione FSM come{+ * * - - / / +}Ho ma non sono riuscito a comprimerlo con meno codice.

Potrebbe essere espresso come una funzione anonima

Un-giocato a golf:

(defn f [a b n]
  (let [ops [+ * - /]]
    (->> [a b 0]
         (iterate (fn [[a b i]]
                    [b
                     ((ops i) a b)
                     (mod (inc i) 4)]))
         (map first)
         (take n))))

Deve essere chiamato con float come (f 6.0 3.0 25)altrimenti si ottengono numeri razionali. In alternativa, è possibile iniziare l'iterazione da [a (float b) 0]cui derivano alcuni caratteri extra.


0

Ottava , 91 byte

@(x,n)eval 'for i=3:n,x(i)=eval([(n=@num2str)(x(i-2)),"*-/+"(mod(i,4)+1),n(x(i-1))]);end,x'

Provalo online!

Alcuni golf:

  • Nessuna parentesi per la prima evalchiamata
  • Nessuna concatenazione per la prima evalchiamata
  • Assegnazione in linea di *-/+(non possibile in MATLAB)
  • Combinato 'ed "evitare di sfuggire agli apostrofi (impossibile in MATLAB)
  • Memorizzazione n=@num2strpoiché viene utilizzata due volte (impossibile in MATLAB)
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.