W tym wyzwaniem, można napisać tłumacza dla 2 Ohm (transkrypcji jako TwoMega ), język oparty luźno na brainfuck z nieskończoną-wymiarowej przestrzeni magazynowej.
Język
2 Ω zawiera trzy części stanu:
Tape , która jest nieskończona lista bitów, wszystkie inicjowany na 0. To ma skrajnie lewą element, ale nie skrajny prawy element.
Pamięci wskaźnik , który jest dodatnią liczbą całkowitą, która ma indeks elementu z taśmy. Wyższy wskaźnik pamięci odnosi się do komórki taśmy po prawej stronie; wskaźnik pamięci 0 oznacza lewy element. Wskaźnik pamięci jest inicjowany na 0.
Hypercube , który jest koncepcyjnie ∞ wymiarową „skrzynka” komórek, z których każda zawiera nieco zainicjowanym z wartością 0. szerokość hipersześcianu jest związana w każdym wymiarze tylko dwóch komórek, ale nieskończoność rozmiarów oznacza liczbę komórki to niepoliczalne .
indeks do hipersześcianu nieskończona listę bitów odnosi się do komórki w hipersześcianu (w taki sam sposób, jak lista skończonych bitów może być używane w odniesieniu do hipersześcianu skończonych wymiarach). Ponieważ taśma jest nieskończoną listą bitów, cała taśma zawsze odnosi się do elementu Hypercube; element ten nazywa się odnośnikiem .
2 Ω nadaje znaczenie 7 różnym znakom:
<
zmniejsza wskaźnik pamięci o 1. Zmniejszenie go poniżej 0 jest niezdefiniowanym zachowaniem, więc nie musisz go obsługiwać.>
zwiększa wskaźnik pamięci o 1.!
odwraca bit w stosunku do odnośnika..
wypisuje bit pod odnośnikiem.^
zamienia bit w komórce wskazanej przez wskaźnik pamięci na taśmie odwrotnością bitu w odnośniku.[x]
uruchamia kod,x
o ile bit przy odnośniku wynosi 1.
Wyzwanie
Twoim zadaniem jest napisanie programu, który pobiera ciąg znaków jako wejście i wykonuje to wejście jako program o wartości 2 Ω .
To jest golf-golf, więc wygrywa najkrótsza poprawna odpowiedź (mierzona w bajtach).
Notatki
- Możesz założyć, że program będzie się składał wyłącznie ze znaków
<>!.^[]
i że[]
będzie odpowiednio zagnieżdżony. - Twój tłumacz powinien być ograniczony tylko dostępną pamięcią w systemie. Powinno być możliwe uruchomienie przykładowych programów w rozsądnym czasie.
Przykładowe programy
Drukuj 1:
!.
Drukuj 010:
.!.!.
Drukuj 0 na zawsze:
![!.!]
Drukuj 0 na zawsze lub 1 na zawsze, jeśli !
jest poprzedzony:
[.]![!.!]
źródło
1
s na taśmie jest zawsze skończona. W rzeczywistości istnieje dość prosty biject między liczbami naturalnymi a stanami taśmy (interpretuj zawartość taśmy jako wsteczną liczbę binarną), co pokazuje, że Hypercube jest w zasadzie nieskończoną tablicą 1D, do której dostęp uzyskuje się poprzez odwracanie bitów w wartość wskaźnika liczby całkowitej , zamiast in / decrementing jak w brainfuck.cat
programu: wydaje się, że nie ma instrukcji do wprowadzania danych..
- wypisuje jedno zero, a następnie istnieje;!^!.
- drukuje jeden, a następnie wychodzi. Więcej by było jednak dobrych. W tej chwili należy zrozumieć zgłoszenia, aby je zweryfikować (a zatem głosować za nimi!)[0,0,0,0,0,0,0...]
(tj. Obecność a!
na początku programu).[.]![!.!]
aby wydrukować wartość tej komórki na zawszeOdpowiedzi:
Python 2 , 167 bajtów
Wypróbuj online!
t jest taśmą. t = 6 oznacza, że taśma jest [0 1 1 0 0 0…]
m oznacza 2 do mocy wskaźnika pamięci. Więc m = 8 oznacza, że wskazujemy bit taśmy 3.
h to hipersześcian. h = 80 (ustawione bity 4 i 6) oznaczają bity w [0 0 1 0…] i [0 1 1 0…] są ustawione.
Aby odczytać bit pod odnośnikiem, sprawdzamy 2 t & h . Aby to przerzucić, wykonujemy h ^ = 2 t .
Tłumaczymy instrukcje na kod Python i wykonujemy wynik. I przechowuje poziom wcięcia pętli while.
źródło
2**t
(-6 bajtów).JavaScript (Node.js) , 148 bajtów
Wypróbuj online!
To wszystko się kończy
Potrzebujesz init jako przesunięcia w prawo o kilka miejsc i zainicjowania bieżącego i prawego jednego bitu adresu jako 1 (
>>>>>>>>^>^<
)Wypróbuj online!
Miejsce
n
w BoolFuck jest zapisane jako(0, 0, ..., 0(n*0), [1], 1, 0, 0, ...)
.Ponieważ
>
robin
=>n+1
To samo, co
<
działaźródło
!>.
drukuje1
w boolfucku, ale tłumaczy, na!>^.
które drukuje 1 w TwoMega (>
nie wpływa na taśmę;^
nie wpływa na taśmę, ponieważ odnośnikiem jest 1)+>;
do[1]00...
1[0]0...
(wyjście 0),!>^.
zrobić(0,0,...)=1, ptr=([0],0,...)
(0,0,...)=1, ptr=(0,[0],...)
(0,0,...)=1, ptr=(0,[1],...)
(wyjście 0), co jest nie tak?!>.
, tylko>
poprawne polecenie w boolfuck ...!
odwraca odnośnik, a nie komórkę taśmy.Brain-Flak Classic , 816 bajtów
Wypróbuj online!
Ten kod został napisany tylko po to, żeby mieć miejsce na napisanie dowodu kompletności Turinga.
Dowód kompletności Turinga
Pokazujemy redukcję z Boolfuck do TwoMega:
To tłumaczenie przechowuje stan Boolfuck w parzystych komórkach taśmy w TwoMega. Wszystkie przetłumaczone polecenia zachowają następujące niezmienniki:
Urywek
!^!
będzie się utrzymywał na[0]0
stałym poziomie i zamieniał pomiędzy0[0]
i[1]1
( gdzie uwaga jest ograniczona do linii na hipersześcianie, do której można dotrzeć bez poruszania wskaźnikiem pamięci). Jako taki służy do tymczasowego umieszczenia bieżącej wartości taśmy w odnośniku dla poleceń Boolfuck, które się nią zajmują.Jeśli TwoMega otrzyma polecenie wejściowe
,
z oczekiwaną semantyką, polecenie Boolfuck,
przetłumaczy się na>^<,!^>[!]!^<
. Ponieważ,
nie jest konieczne udowodnienie, że Boolfuck jest kompletny w Turinga, brak polecenia wejściowego nie wpływa na ten dowód.źródło
Python 3 ,
297284274 bajtów-10 bajtów dzięki ovs i Jonathanowi Allanowi
Wypróbuj online!
źródło
t.discard(p)
->t-={p}
t
jestglobal
.f
jakof(C,p,t=set())
Pip ,
7571 bajtówWypróbuj online!
Tłumaczy kod 2 Ω na równoważny kod Pip i ocenia go.
Używamy
i
do reprezentowania taśmy,v
wskaźnika taśmy * il
hipersześcianu. Pierwsze dwa są wstępnie zainicjowane do użytecznych wartości;l
zaczyna się jako[]
, do którego naciskamy a0
(lPU0
), aby uniknąć problemów z indeksowaniem pustej listy.* W rzeczywistości jest to bitowa negacja wskaźnika taśmy, ponieważ przechowujemy taśmę do tyłu w celu łatwiejszej konwersji na dziesiętną.
Reszta kodu to:
Tabela tłumaczeń:
l@FBi
to odnośnik: element hipersześcianul
w indeksie (konwersjai
z pliku binarnego). Pojawia się często, dlatego nazywamy go_
i zastępujemy_
prawdziwym kodem na końcu.!:_
logicznie neguje odniesienie na miejscu.--viPU0
zmniejszeniav
(przesunięcie wskaźnika taśmy w prawo); następnie przesuwa kolejną0
na lewą stronęi
, aby upewnić się, że wskaźnik taśmy pozostaje w granicach.++v
przyrostyv
(nie ma potrzeby sprawdzania granic, na PO).W_{
uruchamia pętlę, podczas gdy referencja jest prawdziwa (tzn. niezerowa, tj1
.).}
zamyka pętlę.O_
wyprowadza odnośnik bez znaku nowej linii.Wreszcie dla
^
:źródło