Zagraj w golfa jako Purple Interpreter
Fioletowy to esolang, który został zaprojektowany w dwóch głównych celach:
- Być minimalizacją bakłażana , ponieważ po prostu nie ma wystarczającej ilości samomodyfikujących się języków z jedną instrukcją.
- Przyznać możliwość przerażająco małych golfistów. Moje pierwsze przejście w rozsądnie w pełni funkcjonalnym interpreterze Python 2 to tylko 702 bajty i jestem pewien, że bardziej doświadczony golfista mógłby się z tego trochę zgolić.
Twoim celem jest napisanie tłumacza dla tego języka.
Informacje na temat Purple:
Program Purple to sekwencja znaków umieszczonych w nieskończonej, adresowalnej tablicy pamięci, tak że pierwszy znak programu jest umieszczony pod adresem zero. Reszta tablicy (zarówno przed, jak i po zapisaniu programu Purple) jest inicjowana do zera.
Istnieją trzy rejestry w fioletowy, zwane i b , a ja , z których każdy może posiadać podpisane całkowitą i jest inicjowany do zera. i jest również wskaźnikiem instrukcji i zawsze wskazuje na aktualnie wykonywaną instrukcję Purple.
W każdym cyklu tłumacz interpretuje sekwencję trzech ciągłych znaków rozpoczynających się od miejsca w pamięci wskazanego wskaźnikiem instrukcji i próbuje wykonać tę sekwencję jako instrukcję fioletową. Następnie wskaźnik instrukcji jest zawsze zwiększany o 3.
Składniowo instrukcja Purple składa się z trzech znaków (lub ich kodowań) z rzędu, takich jak „ xyz ”.
Pierwszy znak x może być dowolnym z poniższych:
abABio
Symbole te mają następujące znaczenie:
a - Place the result in register a.
b - Place the result in register b.
A - Place the result in the location in memory referred to by register a.
B - Place the result in the location in memory referred to by register b.
i - Set the instruction pointer to the result.
o - Output the result to stdout.
Pozostałe dwa bajty y i z mogą być dowolnymi z poniższych:
abABio1
Każdy z tych symboli ma następujące znaczenie:
a - Return the contents of register a.
b - Return the contents of register b.
A - Return the contents of the memory array at the address stored in register a.
B - Return the contents of the memory array at the address stored in register b.
i - Return the contents of register i (the instruction pointer).
o - Return the value of a single character read from stdin.
1 - Return the literal numeric value 1.
Po pobraniu instrukcji interpreter Fioletowy oceni y, a następnie z , odejmie wynik z od wyniku y , a następnie wykona akcję wskazaną przez x na różnicy.
Jeśli sekwencja trzech znaków (lub ich kodowania) nie jest prawidłową instrukcją w kolorze fioletowym, interpreter zatrzymuje się natychmiast bez żadnych błędów.
Twój tłumacz musi:
- Bądź kompletnym programem, a nie funkcją.
- Nigdy nie wysyłaj do stderr, chyba że EOF zostanie odczytany .
- Zachowuj się identycznie jak implementacja referencyjna na wszystkich dobrze sformułowanych danych wejściowych, które nie obejmują bardzo dużych liczb, w tym programów testowych podanych poniżej. (Cóż, identycznie do czasu - może działać wolniej, ale nie za bardzo!)
Możesz dostarczyć program tłumaczowi w dowolnej formie: odczytać go z pliku, osadzić w programie jako ciąg znaków lub odczytać ze standardowego wejścia.
Przypadki testowe:
Program
ooo
po uruchomieniu z wejściem
z!
powinien ustąpić
Y
Program
bbboobiii
po uruchomieniu z wejściem
It's a cat program.
(lub jakikolwiek inny wkład) powinien dać
It's a cat program.
(lub cokolwiek, co otrzymał), a następnie zacznij od nowa i zrób to samo .
Program
Aoab11bi1bABoAaiba
po uruchomieniu z wejściem
0
powinien ustąpić
0
a następnie zatrzymaj, ale po uruchomieniu z wejściem
1
powinien kontynuować wysyłanie
1
na zawsze.
Program
b1bbb1oAbabaa1ab1Ab1Bi1b
powinien ustąpić
b1bbb1oAbabaa1ab1Ab1Bi1b
Program
aA1aa1bb1oAbbi1bb1bbAb1Bi1b Purple is the awesomest! Why haven't you tried it yet?
!dlroW ,olleG
powinien ustąpić
Hello, World!
Punktacja:
To jest golf golfowy , więc wygrywa najkrótsze źródło w bajtach, potencjalnie zmodyfikowane przez następującą premię.
Premia:
- -10%, jeśli interpreter odczyta nazwę pliku ze standardowego lub argumentu wiersza poleceń i załaduje program z pliku.
źródło
uint32
znaków i MAXINT dla intsOdpowiedzi:
Pyth,
148128121 bajtów (lub 124 * .9 = 111,6, patrz dół)Zestaw testowy
Kod podany w pierwszym wierszu STDIN, wejście do programu Purple w pozostałej części STDIN. Aby użyć kodu z nowymi wierszami, użyj alternatywnej wersji u dołu.
Rozsądnie grał w golfa. Oto przełamania linii i wcięcia dla jasności:
Zasadniczo
#
pętla wykonuje wykonywanie i zatrzymuje się poprzez przerwanie błędów.a
ib
są połączone w jeden zmiennejJ
.Z
jest wskaźnikiem instrukcji.k
jest wprowadzany do programu Purple.H
to taśma reprezentowana jako słownik.b
jest bieżącym wynikiem.Y
jest bieżącym pierwszym bajtem instrukcji.Odczytywanie z pliku:
Podaj nazwę pliku jako pierwszy wiersz STDIN. Testowe uruchomienie:
źródło
JavaScript (ES6), 292 bajty
Wyjaśnienie
Odpowiedzi JavaScript zawsze są dziwne, kiedy
STDIN
iSTDOUT
wymagane są ...Pierwszy monit to dane wejściowe dla ciągu programu. Każdy monit wynikający z
o
instrukcji czyta tylko pierwszy znak.eval
służy do zastąpienia zwykłej frazy, która oszczędza kilka bajtów. Bez golfa i bezeval
programu wygląda tak:źródło
c="charCodeAt"
można zastąpić justc
?array[-1] = 1
jest taki sam jakarray = { "-1": 1 }
. Oba są dostępne za pomocąarray[-1]
.Cejlon,
827792671 bajtówZachowuje się nieco inaczej niż implementacja referencyjna, gdy program próbuje odczytać dane wejściowe w EOF - implementacja referencyjna ulega awarii z błędem TypeError, który jest zbyt kosztowny, aby odtworzyć tutaj (a także prawdopodobnie błąd), więc zwróci -1 zamiast tego ( wielokrotnie, jeśli to konieczne).
(Podczas próby zapisania tego -1 na standardowe wyjście, interpreter zakończy się przepełnieniem błędu. Podobnie będzie, jeśli zostanie wypisana liczba całkowita spoza zakresu Unicode.)
Tłumacz interpretuje program jako pierwszy argument wiersza poleceń (pamiętaj, aby zacytować go dla swojej powłoki, gdy zawiera ona spacje lub inne interesujące rzeczy).
Na Cejlonie możemy tylko łatwo odczytać dane wejściowe liniowo (myślę, że zmieni się to w jednej z następnych wersji), więc kiedy
o
jest używany do czytania, czytam całą linię i buforuję części do przyszłych zastosowań. Wydaje mi się, że działa podobnie w implementacji Pythona po podłączeniu do terminala.Podczas próby wykonania polecenia (części), która nie jest jednym z poprawnych znaków,
nothing
spowoduje wygenerowanie błędu AssertionError, który następnie przechwytuje się w bloku catch wokół głównej pętli.Myślę, że najlepiej powinien to być niestandardowy typ wyjątku (ponieważ błąd może również wystąpić w innych miejscach, jeśli mam błąd), ale zajęłoby to znacznie więcej miejsca, pochłaniając większość ulepszeń, które wprowadziłem od pierwszej wersji.
Niektóre sztuczki używane do gry w golfa:
map
funkcję i tworzymy nową za każdym razemA
lubB
jest ona używana jako x .variable
adnotację, która jest terazl
).E
(dla środowiska) is
(krokowej) - wszystko dzieje się teraz wewnątrzrun
funkcji..integer
do uzyskania punktu kodowego znaku,.hash
daje ten sam wynik. Zatemstring*.hash
jest to samo costring.map(Character.integer)
(daje iterowalne punkty kodowe z łańcucha).is I ...
jest krótszy niżexists ...
.x
) W ciąg znaków"``t``"
jest on krótszy niżt.string
(lub, co użyłem dla znaku,String{t}
).Oto sformatowana (i skomentowana) wersja:
źródło