Zbuduj interpreter dla fałszywego języka opartego na stosie, który pobiera dane wejściowe, interpretuje je i wyprowadza wynik jako tablicę liczb. Powinien iterować po każdym bajcie i wykonywać inną funkcję na podstawie tej tabeli:
0000 (0): Łączenie (Połącz dwie pierwsze liczby w stos tak, jakby były ciągiem. Np .: 12,5 -> 125)
0001 (1): Przyrost (dodaj 1 do liczby na górze stosu)
0010 (2): Zmniejszenie (odejmij jeden od liczby na górze stosu)
0011 (3): Pomnóż (Pomnóż dwie najlepsze liczby na stosie)
0100 (4): Podziel (Podziel liczbę od 2 do góry przez górny numer na stosie)
0101 (5): Dodaj (Dodaj dwa górne numery na stosie)
0110 (6): Odejmij (Odejmij najwyższy numer na stosie od poniższego)
0111 (7): Wykładnik ( Obliczyć liczbę od drugiej do najwyższej do potęgi liczby najwyższej)
1000 (8): Moduł: (Znajdź liczbę od drugiej do najwyższej liczby)
1001 (9): Obróć w prawo (Przesuń stos w dół o jeden. Liczba na dole jest teraz na górze)
1010 (A): Obróć w lewo (Przesuń w górę o jeden. Liczba na górze jest teraz na dole)
1011 (B): Duplikat (skopiuj najwyższy numer, aby pojawił się dwa razy. Np .: 4,1 staje się 4,1,1)
1100 (C): Podwójny duplikat (skopiuj dwa górne numery ze stosu. Np .: 4, 1,2 staje się 4,1,2,1,2)
1101 (D): Zamień (Zamień dwie najlepsze liczby na stosie. Np .: 4,1,2 staje się 4,2,1)
1110 (E): Podwójnie Zamień (Zamień dwie górne cyfry na dwie poniżej. Np .: 1,2,3,4,5 staje się 1,4,5,2,3)
1111 (F): Usuń / Pop (Usuń cyfrę na górze stos)
Na przykład plik zawierający
1 1 BC 5 C 5 B 9 5 - Wejście (szesnastkowe) | | | | | | | | | | 1 2 2 2 4 4 6 6 2 8 - Stack 2 2 2 2 4 6 6 6 2 2 4 2 4 6 4 2 2 2 2 4 2 2 2 2
wyprowadziłoby [8,6,4,2]
Zasady:
- Znaki Unicode / są w porządku, ale ASCII jest najlepszy.
- Bądź kreatywny! Liczy się krótkość, ale kreatywność jest świetna!
- Jeśli bajty są zbyt trudne, użyj
"$iv*/+-^%><dtsz."
lub"0123456789ABCDEF"
zamiast rzeczywistych bajtów. - PRĘDKOŚĆ! Im szybciej, tym lepiej.
- Wynik opiera się na reputacji, ale wielkość jest ogromnym czynnikiem.
Premia:
Spróbuj ukończyć to wyzwanie, używając nowo utworzonego tłumacza możliwie jak najkrótszego ciągu.
Uwaga:
To, co czyni to wyzwanie w przeciwieństwie do innych wyzwań związanych z golfem, polega na tym, że nie ma z tym żadnego kodu. Jeśli, powiedzmy, musiałeś napisać tłumacza brainf * ck, możesz spojrzeć na implementacje innych ludzi. Dzięki temu nie możesz tego zrobić.
Zapomniałem podać datę zakończenia. Myślę, że zrobię to miesiąc po tym, jak to stworzyłem. Osoba z największą liczbą głosów 22 lutego wygrywa!
źródło
Odpowiedzi:
Ruby, 67 linii podstawień wyrażeń regularnych
Postanowiłem napisać interpreter w wyrażeniu regularnym, pozostając przy wydajnych algorytmach.
Mogłem wybrać zwykłe bajty, ale użycie symboli sprawia, że kod jest bardziej czytelny. Oczywiście, gdybyśmy mogli spakować dwie instrukcje w jednym bajcie ...
Łączenie wartości ujemnych powoduje zachowanie dziesiątki uzupełnienia, odzwierciedlając wewnętrzną reprezentację.
Dzielenie jest dzieleniem całkowitym, a reszta nigdy nie jest ujemna.
Jeśli chodzi o rundę bonusową, najkrótszym rozwiązaniem, jakie wymyśliłem ( 13 znaków ), jest czyste rozwiązanie:
źródło
d
(poii
, stos zawiera tylko2
, nic, z czym można zamienić), a końcowe obraca się (cóż, przynajmniej pierwszy, drugi jest tylko zamianą w przebraniu ... ) powinna znajdować się po lewej, a nie po prawej stronie.Zestaw x86 (w systemie Win32)
„SPEED!” Wydaje się tutaj niezwykle ważne i wszyscy wiemy, że pod tym względem nic nie przebije języka asemblera. Zróbmy to w asemblerze!
Jest to implementacja języka w asemblerze x86 (w składni NASM), z liczbami przechowywanymi i interpretowanymi jako 32-bitowe liczby całkowite bez znaku, bezpośrednio przy użyciu natywnego stosu x86. Niedopełnienie stosu i przepełnienie podczas dowolnej operacji arytmetycznej (lub dzielenia przez zero) jest błędem środowiska wykonawczego, kończącym program z komunikatem o błędzie.
Aby to skompilować, użyj czegoś takiego
Program otrzymuje nazwę pliku binarnego zawierającego program w wierszu poleceń (np
nexlang.exe testprg.bin
.). Po zakończeniu drukuje końcową zawartość stosu na standardowe wyjście w formacie czytelnym dla człowieka.Aby pomóc w testowaniu, zapisz następujące elementy w
nex.def
:A następnie napisz swoje programy NEX („nieistniejące”, jak podano w tytule pytania), używając wyżej zdefiniowanej mnemoniki i skompiluj z czymś w rodzaju
Np. W przypadku oryginalnego przypadku testowego użyj
prg.nex
:I na koniec, w przypadku wyzwania „2014” użyj następującego 14-bajtowego programu NEX:
źródło
LEA ESI, [ESI+1]
zamiastINC ESI
?GolfScript, 64 znaki
OK, więc postanowiłem spróbować zagrać w golfa. A czy jest lepszy język do gry w golfa niż GolfScript?
Dogodnie sam GolfScript jest już językiem opartym na stosie z poleceniami jednobajtowymi, a 11 z 16 poleceń mapuje bezpośrednio na wbudowane polecenia GolfScript. Tak więc wszystko, co naprawdę muszę zrobić, aby zinterpretować swój język, to zaimplementować pozostałe pięć poleceń w GolfScript i zbudować tabelę tłumaczeń:
Kod wygląda na rozłożony, ponieważ używam znaku nowej linii jako ograniczników dla tabeli tłumaczeń. Inicjał
0\
wypycha zero na stos i przenosi go poniżej programu wejściowego. The{ }/
Pętla zawierająca większość kodu wykonuje program wejściowego ze stosu i iteracje ciała pętli na każdej ze swych postaci, a końcowa]-1%`
zbiera stos do tablicy, odwraca go (bo próbka wyjście startuje od górnej części stos) i usztywnia go.Ciało pętli rozpoczyna się 16-liniowym ciągiem pojedynczego cudzysłowu.
n%
dzieli ten ciąg przy podziale linii,=
wyszukuje podłańcuch odpowiadający znakowi wejściowemu i~
ocenia podłańcuch jako kod GolfScript.Na koniec, oto implementacje 16 poleceń GolfScript:
`+~
: konkatenuje dwie liczby jako ciągi znaków)
: przyrost(
: zmniejszenie*
: pomnożyć/
: dziel+
: dodaj-
: odejmij?
: podniesienie do władzy%
: moduł](+~
: obróć stos w prawo])\~
: obróć stos w lewo.
: duplikat1$1$
: podwójny duplikat\
: zamiana[@]\+~\
: podwójna zamiana;
: popJestem trochę niezadowolony z podwójnej zamiany - jest brzydka i znacznie dłuższa niż jakiekolwiek inne polecenie. Wydaje się, że powinien istnieć lepszy sposób, ale jeśli tak, to jeszcze go nie znalazłem. Mimo to przynajmniej działa.
Na przykład uruchomienie powyższego programu na danych wejściowych (podanych jako ciąg cudzysłowu GolfScript / Ruby / Perl / Python / itp.):
daje wynik:
Edycja: Udało mi się zapisać dwa kolejne znaki, w sumie 62 znaki , używając bardziej zwartego kodowania tabeli translacji. Jednak to rodzaj poświęcenia czytelności:
Ważnymi cechami tej wersji są
(
na początku pętli, która przesuwa wskaźniki poleceń z 0..15 na -1..14, dzięki czemu mogę umieścić długą sekwencję poleceń jednoznakowych od 1 do 8 na początku stołu. To pozwala mi przechowywać je w osobnym ciągu i eliminować osiem znaków nowej linii; niestety, ta dodatkowa złożoność kosztuje mnie sześć postaci gdzie indziej.źródło
+
w])\+~
Haskell
Dla zabawy stworzyłem rozwiązanie, które nie wykorzystuje żadnych zmiennych , tylko łączy funkcje razem.
źródło
Rubin,
330316 znakówZdecydowałem się na golfa. (Ponieważ to zawsze jest zabawne.)
Główną częścią jest to:
Tłumaczy każdą cyfrę szesnastkową na liczbę całkowitą 10, a następnie używa
[(huge array of strings)]
do znalezienia odpowiedniego ciągu reprezentującego to polecenie. Toeval
jest ten ciąg.Zauważ, że
%w[x y z]
jest to równoważne z['x','y','z']
.Podoba mi się również sposób, w jaki można znaleźć buźki w tej linii! Niektórzy z nich są
:*
:/
:-]
:%
Przykładowy przebieg:
źródło
C -
642634 znakówTylko dla
$iv*/+-^%><dtsz.
dialektu (dodajeq
jako znak końcowy wraz z0
):Rozwiązanie problemu z 2014 r
dididiizs>
. :źródło
free(a);
. I czy nie powinno być<<2
wrealloc
połączeniach?free()
pamięci: Pk, 228
W realizacji podobnych instrukcji jest sporo powtórzeń, które prawdopodobnie można do pewnego stopnia przerobić.
źródło
do
924882622603587569562 znakówZ usuniętymi oczywistymi znakami nowej linii (zachowanymi dla czytelności).
To implementuje interpretację „niedomiaru popycha zero” z komentarza Jana Dvoraka.
Wersja do gry w golfa zmieniła się zasadniczo w porównaniu do wersji bez golfa tutaj, pod (mile widzianą) presją dobrej odpowiedzi Oberona .
Odkryłem, że zastąpienie
switch
oświadczenia na korzyśćif
...else
łańcucha pozwoliło mi odjąć wszystkie cyfry z moich spraw . Zamiast tego inicjujew
zmienną do 47, więc jeden przyrost podnosi ją do 48 (== ascii'0'
), a następnie każdy przyrost zwiększa się,w
aż musimy przejść do'A'
momentu, w którym używamy najczęściej pustego pierwszego argumentu makra, który dodaje dodatkowe 7, aby wstać do „A”. Wersja ungolfed ma pokazać mój ulubionysbrk
/SIGSEGV
sztuczki, aby dostać „wolne” Pamięć bez dalszych przydziałów.źródło
log
nie jest nawet zdefiniowany.R, 428 znaków
Z wcięciami:
W akcji:
źródło
JavaScript, 685
Wersja bez gry w golfa ( gist ):
Wersja golfowa:
Przykład:
źródło
Haskell
Bieganie
źródło
tr
?), Stanie się to możliwe.Common Lisp - 589
Akceptuje dane szesnastkowe bez spacji.
Nie golfowany:
źródło
PHP
nie jest najładniejszy, ale działa.
działa z powłoki, oczekuje, że nazwa pliku będzie pierwszym argumentem. akceptuje dowolny z 3 dialektów (nawet mieszany)
zachowanie nie zdefiniowane dla negatywów lub brakującego indeksu
źródło
PureBasic -
2821891 znakówTo jest interpreter interaktywny - bez pliku, wystarczy wpisać kody o wartości 0-9, AF, a on wykona to polecenie i wyświetli się tak, jak wyświetla go przykładowy post.
Aby wyjść, użyj „X” lub „Q”.
To było naprawdę zabawne :)
edytuj: Po spaniu pomyślałem, że zagram w golfa - pozostawiłem jednak czytelną wersję dla odniesienia.
Wszystko działa tak samo, z wyjątkiem tego, że wyjąłem Q lub X, aby wyjść, wystarczy zamknąć okno, aby wyjść:
źródło
Wspólne Lisp - 586
Bez golfa
Leksykalnie wiąże nowy stos w kodzie makrozwiniętym: brak odniesienia do zmiennej globalnej. Ponadto jest kompilowany do kodu maszynowego.
Przykład
źródło
Python 2, 508 bajtów
Wykorzystuje kodowanie „0123456789ABCDEF”. Jestem naprawdę dumny z tego, jak to się potoczyło. Nie odczytuje pliku, pobiera dane wejściowe ze STDIN, ale jeśli jest to problem, można go łatwo zmienić.
2 rozwiązania problemu 2014:
B11CB3A1AED0A00
(1615 bajtów) - ogólny konkatenator.BB102CD11B513B3622E
(2019 bajtów) - Dużo chłodniej - ocenia na (5 * (10-1)) ^ 2-11źródło
Python 2, 955 bajtów
Czym zajmuje się każda funkcja
źródło