Sequência de Stewie: + * - / + * - /


29

Vamos usar as quatro operações básicas, adição +, multiplicação *, subtração -e divisão /(float, não inteiro).

A sequência de Stewie é definida da seguinte forma:

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.

Desafio:

Pegue dois números inteiros não negativos ( x(1), x(2)) e um número inteiro positivo Ncomo entrada.

x(1)e x(2)serão os dois primeiros números da sua sequência e Nserão o comprimento da sequência que você deve enviar. (Você pode optar por ter a lista com base em 0; nesse caso N, será uma a menos que o comprimento).

  • Você não pode assumir isso x(2) >= x(1).
  • Nsempre será >2se for baseado em 1 ( >1se for baseado em 0).
  • Você não precisa lidar com a divisão com zero erros.
    • Observe o segundo caso de teste. Você não receberá 0, 1e N=6como entrada, pois isso resultará em divisão por zero, mas você deve suportar 0, 1e N=5.
  • Suponha que apenas uma entrada válida seja fornecida.
  • A entrada e a saída podem estar em qualquer formato conveniente, mas você deve suportar pelo menos três dígitos após os pontos decimais se a saída não for um número inteiro.

Casos de teste:

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

Uma função pode tomar x (1) e x (2) como uma lista? Ou argumentos separados?
FlipTack

Tudo o que é conveniente para você :)
Stewie Griffin

Pode Nser baseado em 0? Portanto, tome como entradas 1 menos que o N mostrado em seus exemplos. Eu acho que tomar N-2 é pedir demais para ... :-P
Luis Mendo

Quando você escreve que a saída pode estar em qualquer formato conveniente , isso inclui uma lista com o elemento final no início e os elementos iniciais no final (uma lista invertida)?
Emigna

1
@Emigna, não, eu acho que é um pouco de um trecho ... Os números devem estar na ordem correta
Stewie Griffin

Respostas:


3

MATL , 19 18 17 bytes

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

Entrada está no formato: N(0-based), x(1), x(2)(como cadeias); todos separados por novas linhas.

Experimente online! Ou verifique todos os casos de teste (código ligeiramente modificado; sequências de saída separadas por uma linha em branco).

Explicação

O MATL não possui uma evalfunção adequada , mas U( str2num) pode avaliar expressões numéricas com operadores de infix.

Cada novo termo é calculado e colocado na pilha, mantendo os termos anteriores. A pilha inteira é impressa no final.

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 bytes

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

x1e x2são tomados como uma lista. Exemplo de uso: [1,3] # 8-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

A preguiça torna possível definir uma lista recursiva infinita onde pegamos os primeiros n elementos.

Haskell, 66 bytes

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

Abordagem diferente, um pouco mais. Fim argumento é N, x2, x1. Exemplo de uso: ( (.a).(.).take ) 8 3 1-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

Define 4 funções a, b, ce dque tomam dois argumentos y, x e fazer uma lista, colocando xna frente de uma chamada para o próximo função com ycomo o segundo argumento e x op ycomo o primeiro. Por exemplo aé: a y x = x : (b (x+y) y), bfaz a multiplicação: b y x = x : (c (x*y) y), etc.

Edit: @Michael Klein salvou um byte na 1ª variante ( #). Felizmente, também encontrei um byte para a segunda variante, para que ambos tenham o mesmo comprimento novamente.

Edição II: o @Zgarb encontrou 2 bytes na segunda versão para salvar e I 4 na primeira, para que eles não tenham mais o mesmo comprimento.


Aceitar os argumentos como uma lista (autorizados) para um byte
Michael Klein

Sempre fico confuso se (.)é composto por outras funções: p
tomsmeding

g x=(`take`f)wherenão salva um byte: - /
Bergi

Salve 2 bytes na abordagem alternativa:(h%g)y x=x:g(h x y)y
Zgarb 28/11

@ Zgarb: oh, que bom. Obrigado! BTW, ao editar suas sugestões, encontrei 4 bytes para salvar ao longo do caminho na primeira versão.
nimi 28/11

6

ES6 (Javascript), 79, 67, 65 bytes

ATUALIZAR

  • menos 2 bytes, iniciando com i = 2, conforme sugerido por @ETHProductions
  • Economizou 3 bytes, graças aos excelentes conselhos do @Neil!

Golfe

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

Teste

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
Você não pode usar ++ipara evitar a adição de 1 a iduas vezes?
31416 Neil

1
Ou, como alternativa, a gravação ?S(n,a,i+1,a.push(...)):apode economizar alguns bytes.
31416 Neil

1
Ou talvez você poderia usar o fato de que a.pushretorna o novo comprimento,S=(n,a,i=2)=>i<n?S(n,a,a.push(...)):a
Neil

1
Ainda acho que você pode salvar mais bytes iniciando em i=2embora.
31516 Neil

1
Com a sugestão de Neil, acho que você pode fazer S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"+*-/"[i%4]+a[i-1]))):apara economizar 2 bytes.
ETHproductions

5

Python 3, 90 80 74 bytes

o xnor provavelmente irá destruir esta solução ...

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

A função modifica a lista passada para ela. Use assim:

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

Experimente repl.it!

-6 bytes graças ao cobre


Como você usa apenas Ouma vez, é possível salvar alguns bytes executando '-/+*'[i%4]e removendo a declaração de O. Além disso, você pode contornar as chamadas repetidas strfazendo algo parecido eval('%s'*3%(s[-2],'-/+*'[i%4],s[-1])).
Copper

Ah, sim, e s+=[...]pode ser substituído por s+=...,(observe a vírgula à direita).
Copper

O xnor não é o único que pode destruir sua solução. Há outra pessoa também: Dennis (o mod).
Erik the Outgolfer

Você tem a garantia de receber icomo entrada, portanto, não precisa do valor padrão ( i=2pode ser justo i). Dois bytes desativados.
ArtOfCode 26/11/16

1
Se fosse permitido retornar o nth item na sequência, este é 1 byte menor com recursão: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 bytes

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

Teste-o

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

Teste-o

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

Teste-o

Expandido:

{ # 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 bytes

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

Mal entrou no terceiro lugar! Função sem nome de três argumentos, que usa um operador unário auxiliar ±tal que ±nseja exatamente o enésimo elemento x (n) da sequência Stewie. Os dois primeiros argumentos são x (1) e x (2), e o terceiro argumento é o N, indicando qual x (N) produzimos.

Implementação direta, usando um cálculo mod-4 para escolher qual função binária aplicar aos dois termos anteriores. Escolher a função binária correta, que é o que 1##[#-#2,#/#2,+##]ajuda, usa alguns desses truques divertidos de golfe do Mathematica .


3

05AB1E , 21 19 18 bytes

A entrada é feita na ordem N (com base em 0), x (2) , x (1) .
Economizou 1 byte graças à carusocomputação .

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

Experimente online!

Explicação

 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

Construímos iterativamente a pilha com o elemento mais recente na sequência no topo, mantendo todos os elementos anteriores em ordem.
Em seguida, agrupamos a pilha em uma lista no final para exibir todos os valores de uma só vez.


1
Não consegui descobrir, mas usar XYe UVpode economizar bytes.
Magic Octopus Urn

1
@carusocomputing: Boa captura! Salvei o byte que perdi do registro e não trabalhei na entrada implícita usandoUX :)
Emigna

2

Lisp comum, 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)))

Não é realmente competitivo, mas eu gosto de como é expresso naturalmente:

(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)))

Ignoramos erros ao calcular R, o que faz com que R (e depois B) aceite o valor NIL. Isso permite gerar o resultado atual, mesmo que o próximo valor seja indefinido. Então, eventualmente, o loop falhará, mas isso está dentro das regras.

Testes

Nomeamos a função Fe verificamos que os valores esperados são aproximadamente iguais aos testados.

(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

O motivo do teste aproximado é que os valores calculados são um pouco mais precisos do que o necessário; aqui para(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 bytes

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

Às vezes, as dcrespostas podem ser super longas e, às vezes, super curtas. Tudo depende apenas do desafio em questão, como é o caso de muitos outros idiomas. De qualquer forma, isso solicita uma entrada de linha de comando indexada em um espaço, de 3 números inteiros, x(1), x(2), Napós a chamada e gera cada elemento da sequência em linhas separadas com saídas não inteiras contendo 5 dígitos após o ponto decimal.

Por exemplo, a entrada 6 3 25resulta na seguinte saída:

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 ( -plasinalizador) = 65 bytes

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

Ruby, 79 bytes

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

Suspeito que isso esteja muito longe do ideal (e ainda não olhei para as outras respostas), mas ainda assim é divertido.

Eu queria me divertir um pouco Enumerable#cycle, mas, infelizmente, são 4 caracteres a menos para usar %4.


1

C ++ 14, 118 bytes

[](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);}

Como lambda sem nome, modificando sua entrada. Requer vser um vector<double>ou vector<float>.

Ungolfed e uso:

#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

código de máquina x86-64, 34 bytes

Convenção de chamada = x86-64 System V x32 ABI (registre argumentos com ponteiros de 32 bits no modo longo).

A assinatura da função é void stewie_x87_1reg(float *seq_buf, unsigned Nterms);. A função recebe os valores iniciais x0 e x1 nos dois primeiros elementos da matriz e estende a sequência para pelo menos mais N elementos. O buffer deve ser preenchido com 2 + N-arredondado-para-o-próximo-múltiplo-de-4. (ou seja 2 + ((N+3)&~3), apenas N + 5).

Exigir buffers acolchoados é normal na montagem para funções de alto desempenho ou vetorizadas por SIMD, e esse loop desenrolado é semelhante, portanto, não acho que isso esteja distorcendo as regras demais. O chamador pode facilmente (e deve) ignorar todos os elementos de preenchimento.

Passar x0 e x1 como uma função arg ainda não no buffer nos custaria apenas 3 bytes (para a movlps [rdi], xmm0ou movups [rdi], xmm0), embora isso seja uma convenção de chamada não padrão, pois o System V passastruct{ float x,y; }; em dois registros XMM separados.

Isso é objdump -drw -Mintelproduzido com um pouco de formatação para adicionar comentários

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

Esta implementação de referência C compila (com gcc -Os) um código semelhante. O gcc escolhe a mesma estratégia que eu, de manter apenas um valor anterior em um 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++;
    }
}

Eu experimentei de outras maneiras, incluindo uma versão x87 de dois registros que possui código como:

; 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

Você faria dessa maneira se estivesse buscando velocidade (e o SSE não estava disponível)

Colocar as cargas da memória dentro do loop em vez de uma vez na entrada pode ter ajudado, já que podemos armazenar os resultados sub e div fora de ordem, mas ainda assim precisamos de duas instruções FLD para configurar a pilha na entrada.

Também tentei usar a matemática escalar SSE / AVX (começando com valores em xmm0 e xmm1), mas o tamanho maior da instrução é matador. Usar addps(já que é 1B menor que addss) ajuda um pouquinho. Usei prefixos AVX VEX para instruções não comutativas, pois o VSUBSS tem apenas um byte a mais que SUBPS (e o mesmo comprimento que 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

Testado com este equipamento de teste:

#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;
}

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

Execute o primeiro caso de teste com ./stewie 8 1 3

Se você não possui bibliotecas x32 instaladas, use nasm -felf64e deixe o gcc usando o padrão -m64. Eu usei em mallocvez de float seqbuf[seqlen+8](na pilha) para obter um endereço baixo sem ter que realmente construir como x32.


Curiosidade: O YASM possui um bug: ele usa um rel32 jcc para a ramificação do loop, quando o destino da ramificação tem o mesmo endereço que um símbolo global.

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

monta para ... 11f: 0f 8f db ff ff ff jg 100 <stewie_x87_1reg>




0

Bash, 224 bytes (SEM CONCURSO)

Uma implementação tremendamente grande no BASH .

Executa a tarefa literalmente e faz tudo em um tubo contínuo, sem estruturas de fluxo de controle profanas ou recursão.

Entrada

$ 1, $ 2 - elementos iniciais

$ 3 - tamanho da sequência de destino

Golfe

{ 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

Menos Golfe

{ 
 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

Teste

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

Etapas do pipeline

Gere uma tabela de índices de elementos + op, para cada elemento da sequência de saída (um por linha):

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

Use sed para converter isso em um programa linear bc :

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

alimente isso com bc e deixe fazer todo o trabalho


0

Pitão - 20 bytes

Todos os ncustos me custam.

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

Não funciona online, porque eval.


0

Ceilão, 195 bytes

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;

Formatado e comentado:

// 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;

Exemplo de uso:

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

Exemplo de saída:

[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]

O segundo exemplo mostra como isso lidaria com a divisão por zero. O último exemplo mostra que os resultados divergem um pouco, dependendo do tipo de aritmética (e arredondamento) usado ... Acho que a aritmética de ponto flutuante de 64 bits do Ceilão está um pouco mais próxima do que deveria ser do que o postado na pergunta .


0

Clojure, 99 bytes

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

Esta versão é mais agradável de usar na prática, mas possui 110 bytes:

(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])))))

Tive problemas ao interromper a função iterada e uma sequência cíclica de operações, então tive que usar um contador. Também tentei usar uma tabela de transição FSM como, {+ * * - - / / +}mas não consegui compactá-la com menos código.

Pode ser expresso como uma função anônima

Sem golfe:

(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 ser chamado com carros alegóricos (f 6.0 3.0 25), caso contrário, você obtém números racionais. Como alternativa, a iteração pode ser iniciada a partir da [a (float b) 0]qual traz alguns caracteres extras.


0

Oitava , 91 bytes

@(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'

Experimente online!

Alguns campos de golfe:

  • Sem parênteses na primeira evalchamada
  • Nenhuma concatenação para a primeira evalchamada
  • Atribuição inline de *-/+(não é possível no MATLAB)
  • Combinado 'e "para evitar escapar dos apóstrofos (não é possível no MATLAB)
  • Armazenamento, n=@num2strpois é usado duas vezes (não é possível no MATLAB)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.