Sekwencja Stewiego: + * - / + * - /


29

Użyjmy czterech podstawowych operacji: dodawania +, mnożenia *, odejmowania -i dzielenia /(liczba zmiennoprzecinkowa, nie liczba całkowita).

Sekwencja Stewiego jest zdefiniowana następująco:

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.

Wyzwanie:

Weź dwie nieujemne liczby całkowite ( x(1), x(2)) i jedną dodatnią liczbę całkowitą Njako dane wejściowe.

x(1)i x(2)będą dwie pierwsze liczby twojej sekwencji i Nbędą długością sekwencji, którą musisz wydać. (Możesz wybrać, aby lista była oparta na 0, w którym to przypadku Nbędzie o jeden mniejsza niż długość).

  • Nie możesz tego założyć x(2) >= x(1).
  • Nzawsze będzie >2oparty na 1, ( >1jeśli oparty na 0).
  • Nie musisz obsługiwać dzielenia przez zero błędów.
    • Zwróć uwagę na drugi przypadek testowy. Nie dostaniesz 0, 1, a N=6jako dane wejściowe, ponieważ spowoduje to dzielenie przez zero, ale musisz wspierać 0, 1i N=5.
  • Załóżmy, że podane zostaną tylko prawidłowe dane wejściowe.
  • Dane wejściowe i wyjściowe mogą być w dowolnym dogodnym formacie, ale jeśli dane wyjściowe nie są liczbami całkowitymi, muszą być obsługiwane co najmniej 3 cyfry po przecinku.

Przypadki testowe:

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

Czy funkcja może przyjmować x (1) i x (2) jako listę? Czy osobne argumenty?
FlipTack,

Cokolwiek jest dla ciebie wygodne :)
Stewie Griffin

Czy może Nbyć oparty na 0? Więc weź jako dane wejściowe 1 mniej niż N pokazane w twoich przykładach. Myślę, że biorąc N-2 to zbyt wiele, aby prosić o ... :-P
Luis Mendo,

Kiedy piszesz, dane wyjściowe mogą być w dowolnym dogodnym formacie , czy obejmuje to listę z końcowym elementem na początku i elementami początkowymi na końcu (lista odwrócona)?
Emigna,

1
@Emigna, nie, myślę, że to trochę naciągane ... Liczby powinny być w odpowiedniej kolejności
Stewie Griffin

Odpowiedzi:


3

MATL , 19 18 17 bajtów

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

Wejściowy jest w formacie: N(0-based), x(1), x(2)(napisów); wszystkie oddzielone znakiem nowej linii.

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe (nieznacznie zmodyfikowany kod; sekwencje wyjściowe oddzielone pustą linią).

Wyjaśnienie

MATL nie ma właściwej evalfunkcji, ale U( str2num) może oceniać wyrażenia liczbowe za pomocą operatorów infix.

Każdy nowy termin jest obliczany i umieszczany na stosie, z zachowaniem poprzednich terminów. Cały stos jest drukowany na końcu.

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 bajtów

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

x1i x2są traktowane jako lista. Przykład użycia: [1,3] # 8-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

Lenistwo umożliwia zdefiniowanie nieskończonej listy rekurencyjnej, w której przyjmujemy pierwsze n elementów.

Haskell, 66 bajtów

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

Inne podejście, nieco dłużej. Kolejność argumentem jest N, x2, x1. Przykład użycia: ( (.a).(.).take ) 8 3 1-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

Definiuje 4 funkcje a, b, ci dktóre biorą dwa argumenty y, x i zrobić listę, umieszczając xprzed wywołaniem kolejnej funkcji ze yjako drugi argument i x op yjako pierwszy. Na przykład ato: a y x = x : (b (x+y) y), bczy mnożenie: b y x = x : (c (x*y) y)itd

Edycja: @Michael Klein zapisał bajt w 1. wariancie ( #). Na szczęście znalazłem też jeden bajt dla drugiego wariantu, więc oba mają znowu tę samą długość.

Edycja II: @Zgarb znalazł 2 bajty w drugiej wersji do zapisania, a ja 4 w pierwszej, więc nie są już tej samej długości.


Zaakceptuj argumenty jako listę (dozwoloną) bajtu
Michael Klein

Zawsze się mylę, jeśli (.)składa się z innych funkcji: p
tomsmeding

g x=(`take`f)wherenie zapisuje bajtu: - /
Bergi

Zaoszczędź 2 bajty w alternatywnym podejściu:(h%g)y x=x:g(h x y)y
Zgarb,

@Zgarb: och, to miłe. Dzięki! BTW, podczas edycji w twoich sugestiach znalazłem 4 bajty do zapisania po drodze w pierwszej wersji.
nimi

6

ES6 (JavaScript), 79, 67, 65 bajtów

AKTUALIZACJA

  • minus 2 bajty, zaczynając od i = 2, jak sugeruje @ETHProductions
  • Zaoszczędź 3 bajty dzięki doskonałej radzie @Neil!

Grał w golfa

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
Czy nie możesz użyć, ++iaby uniknąć konieczności idwukrotnego dodania 1 ?
Neil

1
Lub, alternatywnie, pisanie ?S(n,a,i+1,a.push(...)):amoże zaoszczędzić trochę bajtów.
Neil

1
A może przydałby się fakt, że a.pushzwraca on nową długość,S=(n,a,i=2)=>i<n?S(n,a,a.push(...)):a
Neil

1
Nadal uważam, że możesz zaoszczędzić więcej bajtów, zaczynając od i=2.
Neil

1
Sugerując Neila, myślę, że możesz zrobić, S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"+*-/"[i%4]+a[i-1]))):aaby zaoszczędzić 2 bajty.
ETHprodukcje

5

Python 3, 90 80 74 bajty

xnor prawdopodobnie przyjdzie i zniszczy to rozwiązanie ...

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

Funkcja modyfikuje przekazaną do niej listę. Użyj w ten sposób:

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

Spróbuj na repl.it!

-6 bajtów dzięki Copper


Ponieważ używasz tylko Oraz, możesz zapisać kilka bajtów, wykonując '-/+*'[i%4]i usuwając deklarację O. Ponadto możesz być w stanie obejść powtarzające się połączenia str, wykonując coś takiego eval('%s'*3%(s[-2],'-/+*'[i%4],s[-1])).
Miedziany

O tak, i s+=[...]można je zastąpić s+=...,(zwróć uwagę na przecinek końcowy).
Copper

xnor nie jest jedynym, który może zniszczyć twoje rozwiązanie. Jest też inna osoba: Dennis (mod).
Erik the Outgolfer,

Masz gwarancję, że otrzymasz ijako dane wejściowe, więc nie potrzebujesz do tego domyślnej wartości ( i=2może być po prostu i). Dwa bajty wyłączone.
ArtOfCode,

1
Jeśli nzamiast tego dozwolone było zwrócenie th pozycji w sekwencji, jest to 1 bajt krótszy z rekurencją:f=lambda x,n:n<2and x[n-1]or eval('%s'*3%(f(x,n-2),'*-/+'[n%4],f(x,n-1)))
mbomb007 12.12.2016

5

Perl 6 ,  75 71  61 bajtów

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

Sprawdź to

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

Sprawdź to

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

Sprawdź to

Rozszerzony:

{ # 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 bajtów

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

Ledwo wślizgnęłam się na 3 miejsce! Nienazwana funkcja trzech argumentów, która używa pomocniczego operatora jednoargumentowego, ±który ±njest dokładnie n-tym elementem x (n) sekwencji Stewiego. Pierwsze dwa argumenty to x (1) i x (2), a trzeci argument to N wskazujące, który x (N) wyprowadzamy.

Bezpośrednia implementacja, wykorzystująca obliczenia mod-4, aby wybrać, która funkcja binarna ma zostać zastosowana do dwóch poprzednich terminów. Wybór właściwej funkcji binarnej, która 1##[#-#2,#/#2,+##]pomaga, wykorzystuje kilka z tych zabawnych sztuczek golfowych Mathematica .


3

05AB1E , 21 19 18 bajtów

Dane wejściowe są przyjmowane w kolejności N (w oparciu o 0), x (2) , x (1) .
Zaoszczędzono 1 bajt dzięki carusocomputing .

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

Wypróbuj online!

Wyjaśnienie

 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

Iteracyjnie budujemy stos z najnowszym elementem w sekwencji na górze, utrzymując wszystkie poprzednie elementy w porządku.
Następnie zawijamy stos na końcu listy, aby wyświetlić wszystkie wartości naraz.


1
Nie mogłem tego rozgryźć, ale używając XYi UVmogę zaoszczędzić bajty.
Magic Octopus Urn

1
@carusocomputing: Nice catch! Zapisany bajt straciłem z rejestrem nie działa na wejściu niejawny użyciu UX:)
Emigna

2

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

Nie bardzo konkurencyjny, ale podoba mi się sposób, w jaki jest wyrażany całkiem naturalnie:

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

Ignorujemy błędy przy obliczaniu R, co powoduje, że R (a następnie B) może przyjąć wartość NIL. Umożliwia to wyświetlenie bieżącego wyniku, nawet jeśli następna wartość nie jest zdefiniowana. W końcu pętla nie powiedzie się, ale jest to zgodne z regułami.

Testy

Nazywamy funkcję Fi sprawdzamy, czy oczekiwane wartości są w przybliżeniu równe testowanej.

(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

Powodem przybliżonego testu jest to, że obliczone wartości są nieco bardziej precyzyjne niż wymagane; tutaj dla (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 bajtów

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

Czasami dcodpowiedzi mogą być bardzo długie, a czasem bardzo krótkie. Wszystko zależy tylko od wyzwania, jak ma to miejsce w przypadku wielu innych języków. W każdym razie monituje to o oddzielone spacjami jednoindeksowe wejście wiersza poleceń o 3 liczbach całkowitych, x(1), x(2), Npo wywołaniu, i wysyła każdy element sekwencji w osobnych wierszach z wyjściami niecałkowitymi zawierającymi 5 cyfr po przecinku.

Na przykład dane wejściowe 6 3 25dają następujące wyniki:

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 ( -plaflaga) = 65 bajtów

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

Za pomocą:

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

1

Rubinowy, 79 bajtów

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

Podejrzewam, że jest to bardzo dalekie od optymalnego (i jeszcze nie spojrzałem na inne odpowiedzi), ale mimo to jest zabawne.

Chciałem się dobrze bawić Enumerable#cycle, ale niestety, jest o 4 mniej znaków do użycia %4.


1

C ++ 14, 118 bajtów

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

Jako nienazwana lambda modyfikująca dane wejściowe. Wymaga vbyć a vector<double>lub vector<float>.

Niegolfowane i użytkowanie:

#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

kod maszynowy x86-64, 34 bajty

Konwencja wywoływania = x86-64 System V x32 ABI (rejestruje argumenty za pomocą 32-bitowych wskaźników w trybie długim).

Sygnatura funkcji to void stewie_x87_1reg(float *seq_buf, unsigned Nterms);. Funkcja odbiera wartości początkowe x0 i x1 w pierwszych dwóch elementach tablicy i rozszerza sekwencję na co najmniej N więcej elementów. Bufor musi zostać uzupełniony do 2 + N zaokrąglone w górę do następnej wielokrotności 4. (tj. 2 + ((N+3)&~3)lub tylko N + 5).

Wymaganie buforowanych buforów jest normalne przy składaniu w przypadku funkcji o wysokiej wydajności lub wektoryzacji SIMD, a ta rozwijana pętla jest podobna, więc nie sądzę, że zbyt mocno wygina reguły. Dzwoniący może łatwo (i powinien) zignorować wszystkie elementy dopełniające.

Przekazanie x0 i x1 jako funkcji arg jeszcze nie znajdującej się w buforze kosztowałoby nas tylko 3 bajty (dla a movlps [rdi], xmm0lub movups [rdi], xmm0), chociaż byłaby to niestandardowa konwencja wywoływania, ponieważ System V przechodzi struct{ float x,y; };w dwóch oddzielnych rejestrach XMM.

To jest objdump -drw -Mintelwyjście z odrobiną formatowania, aby dodać komentarze

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

Ta implementacja odniesienia C kompiluje (z gcc -Os) do nieco podobnego kodu. gcc wybiera tę samą strategię, co ja, polegającą na zachowaniu tylko jednej poprzedniej wartości w rejestrze.

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

Eksperymentowałem z innymi sposobami, w tym wersją x87 z dwoma rejestrami i kodem:

; 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

Zrobiłbyś to w ten sposób, gdybyś dążył do prędkości (a SSE nie było dostępne)

Umieszczenie ładunków z pamięci w pętli zamiast raz na wejściu mogło pomóc, ponieważ mogliśmy po prostu przechowywać wyniki sub i div poza kolejnością, ale nadal potrzebują dwóch instrukcji FLD, aby ustawić stos przy wejściu.

Próbowałem także użyć matematyki skalarnej SSE / AVX (zaczynając od wartości w xmm0 i xmm1), ale większy rozmiar instrukcji jest zabójczy. Używanie addps(ponieważ jest to o 1B mniej niż addss) pomaga trochę. Użyłem przedrostków AVX VEX dla instrukcji nieprzemiennych, ponieważ VSUBSS jest tylko o jeden bajt dłuższy niż SUBPS (i ma taką samą długość jak 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

Testowane za pomocą tej uprzęży testowej:

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

Połącz z nasm -felfx32 -Worphan-labels -gdwarf2 golf-stewie-sequence.asm &&
gcc -mx32 -o stewie -Og -g golf-stewie-sequence.c golf-stewie-sequence.o

Uruchom pierwszy przypadek testowy za pomocą ./stewie 8 1 3

Jeśli nie masz zainstalowanych bibliotek x32, użyj nasm -felf64i pozostaw gcc, używając domyślnej -m64. Użyłem malloczamiast float seqbuf[seqlen+8](na stosie), aby uzyskać niski adres bez konieczności budowania jako x32.


Ciekawostka: YASM ma błąd: używa rel32 jcc dla gałęzi pętli, gdy cel gałęzi ma ten sam adres co symbol globalny.

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

montuje do ... 11f: 0f 8f db ff ff ff jg 100 <stewie_x87_1reg>




0

Bash, 224 bajty (BEZ KONKURSU)

Niezwykle duża implementacja w BASH .

Podejmuje to zadanie dosłownie i robi wszystko w jednej ciągłej rurze, bez żadnych przeklętych struktur kontroli przepływu lub rekurencji.

Wkład

1 USD, 2 USD - elementy początkowe

3 USD - rozmiar sekwencji docelowej

Grał w golfa

{ 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

Mniej golfa

{ 
 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

Etapy rurociągów

Wygeneruj tabelę wskaźników elementów + op, dla każdego elementu sekwencji wyjściowej (po jednym w wierszu):

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

Użyj sed, aby przekonwertować to na liniowy program 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];
...

nakarm to bc i pozwól mu wykonać całą robotę


0

Pyth - 20 bajtów

Wydajenie wszystkich nkosztuje mnie.

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

Nie działa online, ponieważ eval.


0

Cejlon, 195 bajtów

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;

Sformatowane i skomentowane:

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

Przykładowe użycie:

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

Przykładowe dane wyjściowe:

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

Drugi przykład pokazuje, jak to poradziłoby z dzieleniem przez zero. Ostatni przykład pokazuje, że wyniki różnią się nieco w zależności od tego, jakiego rodzaju arytmetyki (i zaokrąglania) używa ... Myślę, że 64-bitowa arytmetyka zmiennoprzecinkowa Ceylona jest nieco bliższa temu, co powinna być, niż to, co zostało napisane w pytaniu .


0

Clojure, 99 bajtów

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

Ta wersja jest ładniejsza w praktyce, ale ma 110 bajtów:

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

Miałem problem z wywołaniem iterowanej funkcji i cykliczną sekwencją operacji, więc zamiast tego musiałem użyć licznika. Próbowałem także użyć tabeli przejścia FSM, takiej jak, {+ * * - - / / +}ale nie mogłem wycisnąć jej do mniejszej ilości kodu.

Można to wyrazić jako funkcję anonimową

Bez golfa:

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

Musi być wywoływany z (f 6.0 3.0 25)liczbami zmiennoprzecinkowymi, ponieważ w przeciwnym razie otrzymujesz wymierne liczby. Alternatywnie można rozpocząć iterację, [a (float b) 0]która przynosi dodatkowe znaki.


0

Oktawa , 91 bajtów

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

Wypróbuj online!

Niektóre golfa:

  • Brak nawiasów dla pierwszego evalpołączenia
  • Brak konkatenacji dla pierwszego evalpołączenia
  • Przypisanie w linii *-/+(niemożliwe w MATLAB)
  • Połączone 'i "aby uniknąć ucieczki od apostrofów (niemożliwe w MATLAB)
  • Przechowywanie, n=@num2strponieważ jest używane dwukrotnie (niemożliwe w MATLAB)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.