En este desafío, escribirás un intérprete para 2 Ω (transcrito como TwoMega ), un lenguaje basado libremente en el cerebro con un espacio de almacenamiento de dimensiones infinitas.
El idioma
2 Ω contiene tres partes de estado:
La cinta , que es una lista infinita de bits, todos inicializados a 0. Tiene un elemento situado más a la izquierda, pero ningún elemento situado a la derecha.
El puntero de memoria , que es un entero no negativo que es un índice de un elemento en la cinta. Un puntero de memoria más alto se refiere a una celda de cinta más a la derecha; un puntero de memoria de 0 se refiere al elemento más a la izquierda. El puntero de memoria se inicializa a 0.
El Hypercube , que es una "caja" de celdas conceptualmente ∞ -dimensional, cada una de las cuales contiene un bit inicializado a 0. El ancho del Hypercube está limitado en cada dimensión a solo 2 celdas, pero el infinito de dimensiones significa el número de Las células son incontables .
Un índice en el hipercubo es una lista infinita de bits que se refiere a una celda en el hipercubo (de la misma manera que una lista finita de bits podría usarse para referirse a un hipercubo de dimensión finita). Debido a que la cinta es una lista infinita de bits, toda la cinta siempre se refiere a un elemento del hipercubo; Este elemento se llama el referente .
2 Ω da significado a 7 caracteres diferentes:
<
disminuye el puntero de memoria en 1. Disminuirlo por debajo de 0 es un comportamiento indefinido, por lo que no necesita manejarlo.>
incrementa el puntero de memoria en 1.!
le da la vuelta al referente..
saca el bit en el referente.^
reemplaza el bit en la celda señalada por el puntero de memoria en la cinta con el inverso del bit en el referente.[x]
ejecuta el códigox
siempre que el bit en el referente sea 1.
El reto
Su tarea es escribir un programa que tome una cadena como entrada y la ejecute como un programa de 2 Ω .
Este es el código de golf , por lo que gana la respuesta válida más corta (medida en bytes).
Notas
- Puede suponer que el programa consistirá únicamente en los personajes
<>!.^[]
y que[]
estará anidado correctamente. - Su intérprete solo debe estar limitado por la memoria disponible en el sistema. Debería poder ejecutar los programas de muestra en un período de tiempo razonable.
Programas de muestra
Imprimir 1:
!.
Imprimir 010:
.!.!.
Imprimir 0 para siempre:
![!.!]
Imprima 0 para siempre o 1 para siempre si !
se antepone:
[.]![!.!]
fuente
1
s en la cinta siempre es finito. De hecho, existe una biyección bastante simple entre los números naturales y los estados de la cinta (interpretar el contenido de la cinta como un número binario hacia atrás), lo que muestra que el Hypercube es básicamente una matriz 1D infinita, a la que se accede volteando bits en un valor de puntero entero , en lugar de disminuir / disminuir como en brainfuck.cat
programa: no parece haber una instrucción para recibir aportes..
imprime un solo cero y luego existe;!^!.
- imprime uno y luego sale. Sin embargo, más sería bueno. Por el momento, uno debe comprender los envíos para verificarlos (¡y por lo tanto votarlos!)[0,0,0,0,0,0,0...]
(es decir, la presencia de un!
al inicio del programa).[.]![!.!]
para imprimir el valor de esa celda para siempreRespuestas:
Python 2 , 167 bytes
Pruébalo en línea!
t es la cinta. t = 6 significa que la cinta es [0 1 1 0 0 0…]
m es 2 a la potencia del puntero de memoria. Entonces m = 8 significa que estamos apuntando al bit de cinta 3.
h es el hipercubo. h = 80 (conjunto de bits 4 y 6) significa que los bits en [0 0 1 0…] y [0 1 1 0…] están configurados.
Para leer el bit en el referente, verificamos 2 t & h . Para voltearlo, realizamos h ^ = 2 t .
Traducimos las instrucciones al código Python y ejecutamos el resultado. Me almacena el nivel de sangría de los ciclos while.
fuente
2**t
(-6 bytes).JavaScript (Node.js) , 148 bytes
Pruébalo en línea!
Está completando
Necesita init moviéndose a la derecha unos pocos lugares e inicie el bit actual y correcto de la dirección como 1 (
>>>>>>>>^>^<
)Pruébalo en línea!
Place
n
in BoolFuck se escribe como(0, 0, ..., 0(n*0), [1], 1, 0, 0, ...)
.Para
>
, lo hacen
=>n+1
Igual a como
<
funcionafuente
!>.
imprime1
en boolfuck, pero traduce a las!>^.
cuales imprime 1 en TwoMega (>
no afecta la cinta;^
no afecta la cinta ya que el referente es 1)+>;
do[1]00...
1[0]0...
(salida 0),!>^.
do(0,0,...)=1, ptr=([0],0,...)
(0,0,...)=1, ptr=(0,[0],...)
(0,0,...)=1, ptr=(0,[1],...)
(salida 0), ¿qué pasa?!>.
, only>
es un comando válido en boolfuck ...!
invierte el referente, no la celda de la cinta.Brain-Flak Classic , 816 bytes
Pruébalo en línea!
Este código fue escrito solo para tener un lugar para escribir una prueba de integridad de Turing.
Prueba de integridad de Turing
Mostramos una reducción de Boolfuck a TwoMega:
Esta traducción almacena el estado de Boolfuck en las celdas de cinta pares en TwoMega. Todos los comandos traducidos preservarán los siguientes invariantes:
El fragmento
!^!
se mantendrá[0]0
constante e intercambiará entre0[0]
y[1]1
(donde la atención se limita a la línea en el hipercubo accesible sin mover el puntero de memoria). Como tal, se utiliza para poner temporalmente el valor de la cinta actual en el referente de los comandos de Boolfuck que se preocupan por él.Si TwoMega recibiera un comando de entrada
,
con la semántica esperada, el comando Boolfuck,
se traduciría a>^<,!^>[!]!^<
. Como,
no es necesario demostrar que Boolfuck está completo en Turing, la falta de un comando de entrada no afecta esta prueba.fuente
Python 3 ,
297284274 bytes-10 bytes gracias a ovs y Jonathan Allan
Pruébalo en línea!
fuente
t.discard(p)
->t-={p}
t
seaglobal
.f
comof(C,p,t=set())
Pip ,
7571 bytesPruébalo en línea!
Traduce el código de 2 Ω en código Pip equivalente y lo evalúa.
Utilizamos
i
para representar la cinta,v
para el puntero de cinta * yl
para el hipercubo. Los dos primeros vienen preinicializados a valores útiles;l
comienza como[]
, a lo que presionamos a0
(lPU0
) para evitar problemas de indexación-lista-vacía.* En realidad, es la negación bit a bit del puntero de la cinta, porque estamos almacenando la cinta hacia atrás para facilitar la conversión a decimal.
El resto del código es:
La tabla de traducción:
l@FBi
es el referente: elemento de hipercubol
en el índice (convertiri
de binario). Aparece a menudo, por lo que lo llamamos_
y lo reemplazamos_
con el código real al final.!:_
lógicamente niega el referente en su lugar.--viPU0
decrementosv
(mover el puntero de la cinta hacia la derecha); luego empuja a otro0
hacia el lado izquierdoi
para asegurarse de que el puntero de la cinta permanezca dentro de los límites.++v
incrementosv
(sin necesidad de verificación de límites, por OP).W_{
ejecuta un bucle mientras el referente es verdadero (es decir, distinto de cero, es decir1
).}
cierra el cicloO_
da salida al referente sin nueva línea.Finalmente para
^
:fuente