Oto bardzo prosta definicja języka:
A Variable is any string that does not contain ^, <, >, !, or ?
The empty string is a valid variable identifier
The value of every variable starts at 0.
A Statement is one of (var is a Variable, P is a Program):
var^ -> changes var to be equal to 1 more than itself
var<P> -> while var > 0, changes var to be equal to 1 less than itself, then runs P
var! -> output value of var
var? -> ask for non-negative integer as input, increase var by that value
A Program is a concatenation of Statements, running a Program means running each Statement in order
Przykładowe programy (zwróć uwagę, że pusty ciąg znaków jest zmienną, ale używam go oszczędnie dla zachowania przejrzystości, a niektóre zmienne są zerowane w programie, gdy zwykle mają domyślnie 0):
<>: sets the value of the empty string variable to 0
b<>b?b<a^>: asks for b, then adds the value stored in b to a, zeroing b in the process
b<>b?a<>b<a^>: asks for b, then sets a to the value of b, zeroing b in the process
a<>c<>b<a^c^>c<b^> : copies the value in b into a without zeroing it
b<>c<>a<c^c^c<b^>>b! : outputs a multiplied by 2
b^b<a<>a?a!b^> : outputs what you input, forever
Twoim celem jest napisanie najmniejszego tłumacza dla tego języka.
Wartość zmiennej może być dowolnie duża i powinna być ograniczona tylko całkowitą pamięcią, do której ma dostęp Twój język, teoretycznie, ale wymagana jest jedynie obsługa wartości do 2 ^ 256.
Twój program powinien teoretycznie obsługiwać dowolnie długie programy, ale będziesz musiał pracować tylko nad programami o długości poniżej 2 ^ 32 znaków. Musisz również obsługiwać zagnieżdżone pętle o głębokości do 2 ^ 32.
Możesz założyć, że program jest prawidłowym programem i że zawsze otrzymasz nieujemne liczby całkowite, gdy poprosisz o dane wejściowe. Możesz również założyć, że w ciągu wejściowym zawarte są tylko znaki drukowalne ASCII.
Szybkość interpretowanego programu nie ma znaczenia, będzie już boleśnie powolny dla rzeczy tak prostych jak 5-cyfrowe mnożenie, bez optymalizacji.
Jeśli chcesz użyć języka, który nie może racjonalnie zaakceptować danych wejściowych lub wygenerować danych wyjściowych w sposób opisany przez ten język, użyj dowolnej interpretacji, która ma to umożliwić. Dotyczy to każdego powodu, dla którego Twój język nie może wdrożyć niektórych wymaganych zachowań. Chcę, aby wszystkie języki mogły konkurować.
Najkrótszy program wygrywa. Obowiązują standardowe luki.
źródło
Odpowiedzi:
Rubinowy, 182 bajty
Spróbuj tak:
Jak to działa
r
Funkcja tokenizes ciąg wejściowy i wykonuje każdy żeton:Szukamy
$2
dopasowania nazwy zmiennej[^!?^<>]*
, po którym następuje jedno z nich<...>
gdzie...
pasuje zero lub więcej programów (\g
jest rekurencją), w którym$4
to przypadku nie jestnil
!
,?
lub^
znak, przechwycony przez$3
, w którym$4
to przypadku jestnil
.Zatem logika wykonywania tokena jest dość prosta, gdy wcina się go trochę:
źródło
JavaScript (ES6) 184
194 209Edycja Uproszczona (użycie parametrów funkcji dla danych wejściowych i wyjściowych wydawało się dobrym pomysłem, ale tak nie było), zapisano jeszcze 1 bajt thx @ ӍѲꝆΛҐӍΛПҒЦꝆ
Edytuj 2 Zmodyfikowane parsowanie. Logika inkrementacji / wprowadzania jest zapożyczona z odpowiedzi @ Lynn
Mniej golfa
TEST Fragment rozpoczyna ocenę 2016 za pomocą programu opublikowanego przez @Neil. Bądź cierpliwy...
źródło
eval
aby uniknąćreturn
nie jest opcją?Perl, 251 bajtów
Wersja łatwiejsza do odczytania:
To marnuje wiązkę bajtów ustalającą pętle na bezpośrednie skoki, ale skanowanie wstecz w poszukiwaniu pętli uraziło moje poczucie estetyki.
źródło
Standardowy C ++, 400 bajtów
To się kompiluje z
g++ -g test.cpp -Wall -Wextra -pedantic -std=gnu++11
Może uda mi się to trochę skrócić. Jeśli masz jakieś sugestie, prosimy o komentarz.
źródło