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ą N
jako dane wejściowe.
x(1)
i x(2)
będą dwie pierwsze liczby twojej sekwencji i N
będą długością sekwencji, którą musisz wydać. (Możesz wybrać, aby lista była oparta na 0, w którym to przypadku N
będzie o jeden mniejsza niż długość).
- Nie możesz tego założyć
x(2) >= x(1)
. N
zawsze będzie>2
oparty na 1, (>1
jeśli oparty na 0).- Nie musisz obsługiwać dzielenia przez zero błędów.
- Zwróć uwagę na drugi przypadek testowy. Nie dostaniesz
0, 1
, aN=6
jako dane wejściowe, ponieważ spowoduje to dzielenie przez zero, ale musisz wspierać0, 1
iN=5
.
- Zwróć uwagę na drugi przypadek testowy. Nie dostaniesz
- 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
N
być 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 ... :-POdpowiedzi:
MATL ,
191817 bajtówWejś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
eval
funkcji, aleU
(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.
źródło
Haskell,
696864 bajtówx1
ix2
są 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
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
,c
id
które biorą dwa argumentyy
,x
i zrobić listę, umieszczającx
przed wywołaniem kolejnej funkcji zey
jako drugi argument ix op y
jako pierwszy. Na przykłada
to:a y x = x : (b (x+y) y)
,b
czy mnożenie:b y x = x : (c (x*y) y)
itdEdycja: @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.
źródło
(.)
składa się z innych funkcji: pg x=(`take`f)where
nie zapisuje bajtu: - /(h%g)y x=x:g(h x y)y
ES6 (JavaScript),
79,67, 65 bajtówAKTUALIZACJA
Grał w golfa
Test
źródło
++i
aby uniknąć koniecznościi
dwukrotnego dodania 1 ??S(n,a,i+1,a.push(...)):a
może zaoszczędzić trochę bajtów.a.push
zwraca on nową długość,S=(n,a,i=2)=>i<n?S(n,a,a.push(...)):a
i=2
.S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"+*-/"[i%4]+a[i-1]))):a
aby zaoszczędzić 2 bajty.Python 3,
908074 bajtyxnor prawdopodobnie przyjdzie i zniszczy to rozwiązanie ...
Funkcja modyfikuje przekazaną do niej listę. Użyj w ten sposób:
Spróbuj na repl.it!
-6 bajtów dzięki Copper
źródło
O
raz, 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łączeniastr
, wykonując coś takiegoeval('%s'*3%(s[-2],'-/+*'[i%4],s[-1]))
.s+=[...]
można je zastąpićs+=...,
(zwróć uwagę na przecinek końcowy).i
jako dane wejściowe, więc nie potrzebujesz do tego domyślnej wartości (i=2
może być po prostui
). Dwa bajty wyłączone.n
zamiast 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)))
Perl 6 ,
75 7161 bajtówSprawdź to
Sprawdź to
Sprawdź to
Rozszerzony:
źródło
Mathematica, 68 bajtów
Ledwo wślizgnęłam się na 3 miejsce! Nienazwana funkcja trzech argumentów, która używa pomocniczego operatora jednoargumentowego,
±
który±n
jest 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 .źródło
05AB1E ,
211918 bajtówDane wejściowe są przyjmowane w kolejności N (w oparciu o 0), x (2) , x (1) .
Zaoszczędzono 1 bajt dzięki carusocomputing .
Wypróbuj online!
Wyjaśnienie
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.
źródło
XY
iUV
mogę zaoszczędzić bajty.UX
:)Common Lisp, 158
Nie bardzo konkurencyjny, ale podoba mi się sposób, w jaki jest wyrażany całkiem naturalnie:
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ę
F
i sprawdzamy, czy oczekiwane wartości są w przybliżeniu równe testowanej.Powodem przybliżonego testu jest to, że obliczone wartości są nieco bardziej precyzyjne niż wymagane; tutaj dla
(f 6 3 25)
:źródło
dc,
112110108 bajtówCzasami
dc
odpowiedzi 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), N
po 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 25
dają następujące wyniki:źródło
Perl, 62 + 3 (
-pla
flaga) = 65 bajtówZa pomocą:
źródło
Rubinowy, 79 bajtów
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
.źródło
C ++ 14, 118 bajtów
Jako nienazwana lambda modyfikująca dane wejściowe. Wymaga
v
być avector<double>
lubvector<float>
.Niegolfowane i użytkowanie:
źródło
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], xmm0
lubmovups [rdi], xmm0
), chociaż byłaby to niestandardowa konwencja wywoływania, ponieważ System V przechodzistruct{ float x,y; };
w dwóch oddzielnych rejestrach XMM.To jest
objdump -drw -Mintel
wyjście z odrobiną formatowania, aby dodać komentarzeTa 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.Eksperymentowałem z innymi sposobami, w tym wersją x87 z dwoma rejestrami i kodem:
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).Testowane za pomocą tej uprzęży testowej:
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 -felf64
i pozostaw gcc, używając domyślnej-m64
. Użyłemmalloc
zamiastfloat 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.
montuje do ...
11f: 0f 8f db ff ff ff jg 100 <stewie_x87_1reg>
źródło
05AB1E , 12 bajtów
Wypróbuj online!
źródło
Japt , 20 bajtów
Spróbuj
źródło
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
Grał w golfa
Mniej golfa
Test
Etapy rurociągów
Wygeneruj tabelę wskaźników elementów + op, dla każdego elementu sekwencji wyjściowej (po jednym w wierszu):
Użyj sed, aby przekonwertować to na liniowy program bc :
nakarm to bc i pozwól mu wykonać całą robotę
źródło
Pyth - 20 bajtów
Wydajenie wszystkich
n
kosztuje mnie.Nie działa online, ponieważ eval.
źródło
Cejlon, 195 bajtów
Sformatowane i skomentowane:
Przykładowe użycie:
Przykładowe dane wyjściowe:
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 .
źródło
Clojure, 99 bajtów
Ta wersja jest ładniejsza w praktyce, ale ma 110 bajtów:
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:
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.źródło
Oktawa , 91 bajtów
Wypróbuj online!
Niektóre golfa:
eval
połączeniaeval
połączenia*-/+
(niemożliwe w MATLAB)'
i"
aby uniknąć ucieczki od apostrofów (niemożliwe w MATLAB)n=@num2str
ponieważ jest używane dwukrotnie (niemożliwe w MATLAB)źródło