Stackylogic es un lenguaje de programación basado en la lógica me hice a la que tienen en 0
's y 1
' s para la entrada y salida de una única 0
o 1
al finalizar.
Un programa Stackylogic consta de líneas que solo pueden contener los tres caracteres 01?
, así como exactamente uno <
al final de una de las líneas. Las líneas pueden no estar vacío y la línea con el <
deben tener al menos una 0
, 1
o ?
antes de ella.
Aquí hay un programa de muestra que (como explicaré) calcula la NAND de dos bits:
1
?<
11
?
0
Cada línea en un programa Stackylogic se considera una pila , con la parte inferior a la izquierda y la parte superior a la derecha. Implícitamente, hay una pila vacía (línea vacía) antes de la primera línea de un programa y después de la última línea.
El <
, que llamaremos el cursor , marca la pila para comenzar cuando se ejecuta un programa Stackylogic. La ejecución de un programa Stackylogic procede de la siguiente manera:
Saque el carácter superior de la pila a la que apunta actualmente el cursor.
- Si el personaje es
?
, solicite al usuario a0
o a1
y actúe como si ese fuera el personaje. - Si el personaje es
0
, mueva el cursor una pila hacia arriba (a la línea sobre la línea actual). - Si el personaje es
1
, mueva el cursor una pila hacia abajo (a la línea debajo de la línea actual).
- Si el personaje es
Si la pila a la que se mueve el cursor está vacía, muestre el último valor que se extrajo de una pila (siempre una
0
o1
) y finalice el programa.De lo contrario, si la pila a la que se mueve el cursor no está vacía, regrese al paso 1 y repita el proceso.
Tenga en cuenta que los programas de Stackylogic siempre terminan porque eventualmente deben agotar sus pilas.
Ejemplo NAND
En el programa NAND, el cursor comienza en ?
:
1
?<
11
?
0
Asumiremos que el usuario ingresa una 1
vez que ?
aparece, lo que significa que el cursor se moverá hacia abajo, haciendo que el programa se vea así:
1
11<
?
0
Ahora hay un plano 1
en la parte superior de la pila del cursor. Está debidamente reventado y el cursor se mueve de nuevo:
1
1
?<
0
Ahora suponga que el usuario ingresa 0
para el ?
, lo que significa que el cursor se moverá hacia arriba:
1
1<
0
Nuevamente, a 1
está en la pila del cursor, de modo que el cursor aparece y se mueve hacia abajo:
1
<
0
Finalmente, la pila del cursor está vacía, por lo que aparece el último valor 1
, se emite y finaliza el programa.
Esto es exacto para una compuerta NAND porque lo 1 NAND 0
es 1
. Por supuesto, esto funciona para las otras tres entradas de dos bits si desea verificar.
O ejemplo
Este programa Stackylogic simula una puerta OR :
?
?<
Es fácil ver que una entrada inicial de 1
empujará el cursor a la pila vacía implícita debajo de la última línea, finalizando el programa y generando el 1
que solo se ingresó.
Por 00
otro lado, para una entrada de , el cursor se abrirá camino hacia la pila vacía implícita en la parte superior, finalizando el programa y generando la última 0
entrada.
Desafío
Escriba un programa o función que tome un programa Stackylogic como una cadena y lo ejecute, imprimiendo o devolviendo el resultado 0
o 1
.
Luego de ?
's, puede solicitar al usuario una entrada 0
o 1
, o leer el valor de una cadena preestablecida de 0
' sy 1
'que también toma como entrada. (Esto podría ser otra entrada de cadena a su programa / función o simplemente podría asumir que la primera o última línea de la cadena de programa será la secuencia de entrada).
Puede suponer que el programa y la entrada siempre están bien formados. Opcionalmente, puede suponer que los programas de entrada vienen con una nueva línea final (aunque recuerde que siempre hay una pila vacía implícita al final).
El código más corto en bytes gana.
Más programas de muestra
ZERO
0<
ONE
1<
BUFFER
?<
NOT
1
?<
0
AND
?<
?
NAND
1
?<
11
?
0
OR
?
?<
NOR
1
?
00
?<
0
XOR(v1)
?
0
1?<
?
0
XOR(v2)
?
?<
11
?
0
XNOR(v1)
1
?
0?<
1
?
XNOR(v2)
1
?
00
?<
?
MEDIAN(v1)
1
???<
0
MEDIAN(v2)
?
1?<
??
fuente
?\1?<\??
. Alternativamente, aquí hay una implementación simétrica de 5 líneas:?\?0\?<\?1\?
1\???<\0
.111\???????<\000
.Respuestas:
Retina ,
79787368666563625544 bytesEl recuento de bytes asume la codificación ISO 8859-1.
La entrada es a través de STDIN y se espera que sea la entrada del usuario separada por dos avances de línea del código fuente.
Pruébalo en línea! (Las primeras dos líneas habilitan un conjunto de pruebas, donde cada línea es un caso de prueba separado en
/
lugar de avances de línea).No estoy completamente seguro de lo que sucedió aquí.
Esto se siente como una solución realmente torpe yeste no es realmente el tipo de problema para el que se hizo Retina, pero aún supera todas las respuestas actuales por alguna razón.Explicación
La versión final de esto en realidad terminó siendo bastante simple.
La primera etapa es simplemente un bucle (debido a la
+
opción) que hace la interpretación real del lenguaje. La etapa es una sola sustitución de expresiones regulares, pero en realidad son tres sustituciones diferentes comprimidas en una sola etapa, al hacer uso del hecho de que capturar grupos de ramas no utilizadas simplemente se considera vacío durante la sustitución.Procesamiento
?
:Esto simplemente toma el primer carácter de la entrada, luego coincide con los caracteres arbitrarios hasta que encuentra
?<
, y pone ese primer carácter delante de<
(eliminando?
).Procesamiento
0
:Esto coincide con la línea que precede a a
0<
y la coloca después de la<
eliminación0
. (Efectivamente, esto simplemente elimina0
y mueve la<
línea hacia arriba).Procesamiento
1
:Más o menos lo mismo, excepto que movemos
<
una línea hacia abajo mientras eliminamos a1
. Un detalle importante a tener en cuenta es el uso de en+
lugar de*
, es decir, requerimos que la siguiente línea no esté vacía.La parte interesante es descubrir por qué esto funciona y por qué no necesitamos hacer un seguimiento del último valor que obtuvimos para determinar el resultado final. Para hacer eso, debemos considerar cómo puede terminar el ciclo anterior. Dado que cada posible coincidencia cambia la cadena (ya que al menos se elimina un carácter de ella), solo necesitamos considerar los casos en que la coincidencia falla por completo.
Si el carácter que está delante
<
es?
la única forma de que falle la coincidencia es que no hay ningún personaje sin salto de línea en ningún lugar delante de él, pero eso no puede suceder porque estamos garantizados de que siempre hay suficiente entrada.Si el carácter delante de
<
es0
, la expresión regular siempre coincidirá, ya que siempre hay otra línea por encima de la actual (que puede ser la línea vacía que separa la entrada del código fuente).Si el carácter delante de
<
es1
, la expresión regular fallará si estamos en la última línea (ya¶
que no coincidirá) o si la siguiente línea está vacía (ya.+
que no coincidirá). Tenga en cuenta que ambos casos corresponden a la finalización del programa después de hacer estallar a1
.Finalmente, también existe la posibilidad de que
<
no esté precedido por ninguno de?01
. Resulta que solo podemos llegar a esta situación haciendo estallar0
ay subiendo a una línea vacía, de modo que<
ahora está precedido por un salto de línea.Entonces, cuando el programa termina en a
1
, el<
seguirá siendo después de eso1
. Pero si el programa termina en a0
, se habrá movido a una línea vacía. Podemos convertir fácilmente esta información en la salida deseada con una simple etapa de coincidencia:Esto simplemente cuenta las coincidencias de
1<
en la cadena. Según el razonamiento anterior, esto será1
si el programa terminó en a1
, y0
si terminó en a0
.fuente
Convexo ,
10295 bytesBueno, un lenguaje basado en una lista de pilas codificado en un lenguaje basado en pilas resultó ser bastante difícil.
Marque mis palabras: ¡Llegaré a 100 bytes o menos!EDITAR: ¡Éxito!Pruébalo en línea!
La entrada del programa es a través de argumentos de línea de comando. De entrada
0
s y1
s normalmente (en TIO, esto significa salto de línea separados en el cuadro de "entrada").Explicación:
Todo el código se puede dividir en tres partes:
Este bit simplemente toma el programa de entrada y lo convierte en una matriz de líneas, y también agrega
" "
líneas al comienzo de la matriz. Dado que las matrices convexas se ajustan, bastará con tener una pila vacía al principio.Esta parte determina con qué línea (o pila) comenzar la ejecución. Busca a través de cada línea y pone el número de pila correcto en la
M
variable.Esta es la parte divertida! Continuamente se repite hasta que llega a una línea con solo un espacio (
" "
) (que simboliza una pila vacía). Si la línea no está vacía, hace lo siguiente:?
, ingrese y agregue ese carácter a la línea.0
, mueva el puntero de línea hacia arriba uno.1
, mueva el puntero de línea hacia abajo uno.(espacio), imprima el elemento emergente más reciente y finalice el programa.
fuente
Código de máquina x86 de 32 bits, 70 bytes
En hexadecimal:
La entrada es una cadena de varias líneas terminada en NULL (separada por salto de línea) pasada a través de ESI. Se supone que la entrada del usuario es la primera línea. Devuelve '0' / '1' en AL.
Desmontaje
fuente
JavaScript (ES6),
136138Asumiendo una nueva línea de terminación en el programa
Menos golf
Prueba
fuente
05AB1E ,
58565553515046 bytes¡ Ahorré 2 bytes gracias a Emigna ! Código:
Utiliza la codificación CP-1252 . Pruébalo en línea! .
fuente
Python 3,
147146145144 bytes1 byte gracias a @Lynn.
fuente
Pitón 3, 318
F es el programa, z es la entrada. Sí, mis nombres de variables son una locura.
fuente
ES6, 190 bytes
Usar como
f(program, input)
fuente
[...o]
lugar deo.split``
y use enfor
lugar dewhile
, ya que eso le permite mover dos expresiones a losfor
dos bytes que se guardan. Un par de consejos específicos: creo que suNumber
transmisión es innecesaria, ya que la*2
enviará para usted, y simplemente leeríai
usandoj=0
yi[j++]
que creo ahorra 11 bytes.f=
, las funciones anónimas están permitidas.Java,
256255231219215213 bytesDemo en Ideone.
Toma el programa y la entrada como argumentos y devuelve el resultado como un entero.
fuente
for
bucle, pero ¿qué significa su primer comentario?int f(String[]I)...
y puede evitar elString[]p=I.split("\n");
int f(String[]P)
->(String[]I){...
PHP (<7.0),
195192 bytesToma el programa como primer argumento y cada valor como argumento adicional.
Tenga en cuenta que probé esto con espacios divididos ("", ..) asn en lugar de líneas nuevas, pero debería funcionar de todos modos.
Da un aviso obsoleto si se ejecuta en php> 5.3.
También da una advertencia si sale de la parte superior del programa. Sin embargo, todavía funciona y sale correctamente, así que está bien.
fuente
C,
264249244242A C no le va tan bien manipulando cadenas, pero esto es bastante corto.
Funciona escaneando la cadena para el cursor (
<
), retrocediendo 1 lugar, leyendo el comando, reemplazándolo con untab
carácter y moviendo una línea hacia adelante o hacia atrás. La entrada tiene la forma de una matriz de caracteres C, comochar array[]="1\n?<\n11\n?\n0";result = f(array);
, aunque también se permiten retornos de carro.Aunque la cadena de entrada se modifica, la longitud no se modifica.
Programa de prueba
Ejecute este programa con cada caso de prueba como un parámetro separado, utilizando una barra invertida única en lugar de líneas nuevas. Los casos de prueba estarán separados por una línea en blanco.
fuente