Cree un intérprete para un lenguaje falso basado en la pila que obtenga una entrada, la interprete y emita el resultado como una matriz de números. Debe recorrer cada byte y realizar una función diferente basada en esta tabla:
0000 (0): Concatenar (Combina los dos números superiores en una pila como si fueran una cadena. Ej: 12,5 -> 125)
0001 (1): Incremento (Agrega 1 al número en la parte superior de la pila)
0010 (2): Decremento (Resta uno del número en la parte superior de la pila)
0011 (3): Multiplica (Multiplica los dos números superiores en la pila)
0100 (4): Divide (Divide el número del segundo al superior por el número superior en la pila)
0101 (5): Sumar (Agregar los dos números superiores en la pila)
0110 (6): Restar (Restar el número superior en la pila del que está debajo)
0111 (7): Exponente ( Calcule el número del segundo al superior a la potencia del número superior)
1000 (8): Módulo: (Encuentre el módulo del segundo número superior al superior)
1001 (9): girar a la derecha (desplazar la pila hacia abajo. El número en la parte inferior está ahora en la parte superior)
1010 (A): girar a la izquierda (desplazar la pila hacia arriba. El número en la parte superior ahora está en la parte inferior)
1011 (B): Duplicar (Copie el número superior para que aparezca dos veces. Ej: 4,1 se convierte en 4,1,1)
1100 (C): Duplicado doble (Copie los dos números superiores en la pila. Ej: 4, 1,2 se convierte en 4,1,2,1,2)
1101 (D): Intercambia (Intercambia los dos números superiores en la pila. Ej: 4,1,2 se convierte en 4,2,1)
1110 (E): Doble Intercambiar (Intercambie los dos números superiores con dos debajo de ellos. Ej: 1,2,3,4,5 se convierte en 1,4,5,2,3)
1111 (F): Eliminar / Pop (Eliminar el número en la parte superior de la pila)
Por ejemplo, un archivo que contiene
1 1 BC 5 C 5 B 9 5 - Entrada (hexadecimal) El | El | El | El | El | El | El | El | El | El | 1 2 2 2 4 4 6 6 2 8 - Pila 2 2 2 2 4 6 6 6 2 2 4 2 4 6 4 2 2 2 2 4 2 2 2 2
daría como resultado [8,6,4,2]
Reglas:
- Los símbolos / Unicode están bien, pero ASCII es el mejor.
- ¡Ser creativo! La escasez cuenta, ¡pero la creatividad es genial!
- Si los bytes son demasiado difíciles, use
"$iv*/+-^%><dtsz."
o en"0123456789ABCDEF"
lugar de bytes reales. - ¡VELOCIDAD! Cuanto más rápido, mejor.
- El puntaje se basa en la reputación, pero el tamaño es un factor enorme.
Prima:
Intente completar este desafío utilizando su intérprete recién creado con la menor longitud de cadena posible.
Nota:
Lo que hace que esto sea un desafío en comparación con otros desafíos de golf de código es que no hay código para seguir con esto. Si, digamos, tuviera que escribir un intérprete brainf * ck, podría mirar las implementaciones de otras personas. Con esto, no puedes hacer eso.
Olvidé poner una fecha de finalización en esto. Supongo que lo haré un mes desde que creé esto. ¡La persona con los votos más altos al 22 de febrero gana!
fuente
Respuestas:
Ruby, 67 líneas de sustituciones regex
Decidí escribir el intérprete en expresiones regulares, mientras me apegaba a algoritmos eficientes.
Podría haber elegido bytes simples, pero usar símbolos hace que el código sea más legible en mi opinión. Por supuesto, si pudiéramos empacar dos instrucciones en un byte ...
La concatenación de valores negativos da como resultado un comportamiento del complemento de diez, que refleja la representación interna.
La división es una división entera y el resto nunca es negativo.
En cuanto a la ronda de bonificación, la solución más corta que se me ocurrió ( 13 caracteres ) es una solución limpia:
fuente
d
(despuésii
, la pila contiene solo2
, nada para intercambiar), y la final gira (bueno, al menos la primera, la segunda es solo un intercambio disfrazado ... ) debe estar a la izquierda, no a la derecha.Ensamblado x86 (en Win32)
"VELOCIDAD" parece ser muy importante aquí, y todos sabemos que nada mejor que el lenguaje ensamblador en ese sentido. Entonces, ¡hagamos eso en la asamblea!
Esta es una implementación del lenguaje en lenguaje ensamblador x86 (en sintaxis NASM), con los números almacenados e interpretados como enteros de 32 bits sin signo, utilizando directamente la pila nativa x86. El desbordamiento de pila y el desbordamiento durante cualquier operación aritmética (o división por cero) es un error de tiempo de ejecución, que termina el programa con un mensaje de error.
Para compilar esto, use algo como
El programa recibe el nombre del archivo binario que contiene el programa en la línea de comando (por ejemplo
nexlang.exe testprg.bin
). Cuando finaliza, imprime el contenido final de la pila a la salida estándar en un formato legible para humanos.Para ayudar con las pruebas, guarde lo siguiente en
nex.def
:Y luego escriba sus programas NEX ("no existentes", como se mencionan en el título de la pregunta) utilizando los mnemónicos definidos anteriormente, y compile con algo como
Por ejemplo, para el caso de prueba original, use lo siguiente
prg.nex
:Y finalmente, para el desafío "2014", use el siguiente programa NEX de 14 bytes:
fuente
LEA ESI, [ESI+1]
lugar deINC ESI
?GolfScript, 64 caracteres
OK, así que decidí probar y jugar golf. ¿Y qué mejor lenguaje para jugar al golf que GolfScript?
Convenientemente, el propio GolfScript ya es un lenguaje basado en la pila con comandos de un solo byte y, como sucede, 11 de sus 16 comandos se asignan directamente a los comandos integrados de GolfScript. Entonces, todo lo que realmente necesito hacer para interpretar su lenguaje es implementar los cinco comandos restantes en GolfScript y crear una tabla de traducción:
El código parece un poco extendido, porque estoy usando nuevas líneas como delimitadores para la tabla de traducción. La inicial
0\
empuja un cero a la pila y lo mueve debajo del programa de entrada. El{ }/
bucle, que comprende la mayor parte del código, saca el programa de entrada de la pila e itera el cuerpo del bucle sobre cada uno de sus caracteres, y el final]-1%`
recoge la pila en una matriz, la invierte (porque su salida de muestra comienza desde la parte superior del pila) y lo stringifica.El cuerpo del bucle comienza con una cadena entre comillas simples de 16 líneas.
n%
divide esta cadena en los saltos de línea,=
busca la subcadena correspondiente al carácter de entrada y~
evalúa la subcadena como código GolfScript.Finalmente, aquí están las implementaciones de GolfScript de los 16 comandos:
`+~
: concatenar dos números como cadenas)
: incremento(
: decremento*
: multiplicar/
: dividir+
: agregar-
: restar?
: subir al poder%
: módulo](+~
: girar la pila hacia la derecha])\~
: girar la pila hacia la izquierda.
: duplicado1$1$
: duplicado doble\
: intercambio[@]\+~\
: doble intercambio;
: popEstoy un poco descontento con el doble intercambio: es feo y mucho más largo que cualquiera de los otros comandos. Parece que debería haber una mejor manera, pero si es así, aún no la he encontrado. Aún así, al menos funciona.
Por ejemplo, ejecutando el programa anterior en la entrada (dada como una cadena de comillas dobles GolfScript / Ruby / Perl / Python / etc.):
produce la salida:
Editar: logré guardar dos caracteres más, para un total de 62 caracteres , usando una codificación más compacta de la tabla de traducción. Sin embargo, sacrifica la legibilidad:
Las características notables de esta versión incluyen el
(
comienzo del ciclo, que cambia los índices de comando de 0..15 a -1..14 para que pueda colocar la secuencia larga de comandos de un solo carácter de 1 a 8 al principio de la mesa. Esto me permite almacenarlos en una cadena separada y eliminar las ocho nuevas líneas que los delimitan; Por desgracia, la complejidad adicional me cuesta seis caracteres en otros lugares.fuente
+
en])\+~
Haskell
Solo por diversión, hice una solución que no usa ninguna variable , solo combina funciones juntas.
fuente
Ruby,
330316 caracteresDecidí jugar al golf. (Porque eso siempre es divertido).
La parte principal es esta:
Traduce cada dígito hexadecimal en un entero de base 10 y luego usa
[(huge array of strings)]
para encontrar la cadena correcta que representa ese comando. Entonceseval
es esa cuerda.Tenga en cuenta que
%w[x y z]
es equivalente a['x','y','z']
.¡También me gusta cómo puedes encontrar caras sonrientes en esa línea! Algunos de ellos son
:*
:/
:-]
:%
Ejecución de muestra:
fuente
C -
642634 caracteres$iv*/+-^%><dtsz.
Solo para el dialecto (se agregaq
como carácter final, junto con0
):Solución para el desafío 2014:
dididiizs>
.fuente
free(a);
. Y, ¿no debería estar<<2
en lasrealloc
llamadas?free()
memoria: Pk, 228
Hay una buena cantidad de repeticiones en la implementación de instrucciones similares, que probablemente pueden ser eliminadas en cierta medida.
fuente
C
924882622603587569562 caracteresCon nuevas líneas obvias eliminadas (retenidas para facilitar la lectura).
Esto implementa la interpretación de "flujo inferior empuja cero" del comentario de Jan Dvorak.
La versión de golf en realidad cambió sustancialmente en comparación con la versión no golfista aquí, bajo la presión (bienvenida) de la excelente respuesta de Oberon .
Descubrí que reemplazar la
switch
declaración a favor de unaif
...else
cadena me permitió descifrar todos los dígitos de mis casos . En su lugar, inicializa law
variable a 47, por lo que un incremento la eleva a 48 (== ascii'0'
) y luego cada caso se incrementaw
hasta que necesitemos saltar hasta'A'
el punto en el que utilizamos el primer argumento macro en su mayoría vacío, que agrega un 7 extra para levantarse a 'A'. La versión ungolfed no mostrar mi favoritosbrk
/SIGSEGV
truco para conseguir la memoria "libre" sin más asignaciones.fuente
log
ni siquiera está definido.R, 428 caracteres
Con hendiduras:
En acción:
fuente
JavaScript, 685
Versión sin golf ( esencia ):
Versión de golf:
Ejemplo:
fuente
Haskell
Corriendo
fuente
tr
?), Entonces es posible.Lisp común - 589
Acepta entradas hexadecimales sin espacios.
Sin golf:
fuente
PHP
No es el más bonito, pero funciona.
se ejecuta desde shell, espera un nombre de archivo como primer argumento. acepta cualquiera de los 3 dialectos (incluso mixto)
comportamiento no definido para negativos o índice perdido
fuente
PureBasic -
2821891 caracteresEste es un intérprete interactivo: no hay archivo, solo ingresa los códigos dados 0-9, AF, y ejecutará ese comando y se mostrará como lo muestra la publicación de ejemplo.
Use "X" o "Q" para salir.
Esto fue muy divertido de hacer :)
editar: Después de dormir, pensé que lo jugaría golf, aunque dejé la versión legible para referencia.
Todo funciona igual, excepto que he quitado la Q o la X para salir, solo cierra la ventana para salir:
fuente
Lisp común - 586
Sin golf
Léxico une una pila nueva en el código macroexpandido: sin referencia a una variable global. Además, se compila en código máquina.
Ejemplo
fuente
Python 2, 508 bytes
Utiliza la codificación "0123456789ABCDEF". Estoy realmente orgulloso de cómo resultó este. No lee el archivo, recibe información de STDIN, pero si eso es un problema, podría cambiarse fácilmente.
2 soluciones para el problema de 2014:
B11CB3A1AED0A00
(1615 bytes) - Concatenador genérico.BB102CD11B513B3622E
(2019 bytes) - Mucho más fresco - Evalúa a (5 * (10-1)) ^ 2-11fuente
Python 2, 955 bytes
Qué hace cada función
fuente