Starry es un divertido lenguaje de programación esotérico en el que el código consiste solo en +*.,`'
donde el comando real representado por cada uno de esos caracteres está determinado por el número de espacios en frente de él. Eso hace que sea complicado incluso para los desafíos de salida fija de golf, porque los diferentes comandos pueden representar cantidades muy diferentes de bytes. En particular, los literales numéricos tienen una representación unaria que hace que sea necesario construir números más grandes al operar con números más pequeños.
Por lo tanto, este desafío se trata de escribir un programa que pueda jugar golf a tales programas Starry.
¿Cómo funciona Starry?
(Algunos detalles se dejan sin especificar en esolangs, así que voy con el comportamiento del intérprete de Ruby ).
Starry es un lenguaje basado en la pila, con una sola pila de valores enteros de precisión arbitraria (que inicialmente está vacía).
Los únicos caracteres significativos son:
+*.,`'
y espacios. Todos los demás personajes son ignorados. Cada secuencia de espacios seguida por uno de esos caracteres que no son espacios representa una sola instrucción. El tipo de instrucción depende del carácter no espacial y el número de espacios.
Las instrucciones son:
Spaces Symbol Meaning
0 + Invalid opcode.
1 + Duplicate top of stack.
2 + Swap top 2 stack elements.
3 + Rotate top 3 stack elements. That is, send the top stack element
two positions down. [... 1 2 3] becomes [... 3 1 2].
4 + Pop and discard top of stack.
n ≥ 5 + Push n − 5 to stack.
0 mod 5 * Pop y, pop x, push x + y.
1 mod 5 * Pop y, pop x, push x − y.
2 mod 5 * Pop y, pop x, push x * y.
3 mod 5 * Pop y, pop x, push x / y, rounded towards -∞.
4 mod 5 * Pop y, pop x, push x % y. The sign of the result matches the sign of y.
0 mod 2 . Pop a value and print it as a decimal number.
1 mod 2 . Pop a value and print it as an ASCII character. This throws an error
if the value is not in the range [0, 255].
n ` Mark label n.
n ' Pop a value; if non-zero, jump to label n.
Tenga en cuenta que el intérprete escanea el código fuente de las etiquetas antes de que comience la ejecución, por lo que es posible saltar hacia adelante y hacia atrás.
Por supuesto, Starry también tiene comandos de entrada (que se usan de forma ,
análoga a .
), pero estos son irrelevantes para este desafío.
El reto
Dada una cadena, genere un programa Starry que no tome entrada e imprima esa cadena exactamente en STDOUT.
Puede escribir un programa o función, tomando la entrada a través de STDIN (o la alternativa más cercana), argumento de línea de comando o argumento de función y generando el resultado a través de STDOUT (o la alternativa más cercana), el valor de retorno de la función o el parámetro de función (out).
Puede suponer que la cadena no tiene más de 128 caracteres y que consistirá solo en caracteres ASCII imprimibles (puntos de código 0x20 a 0x7E).
Su solución debería procesar cualquier entrada de este tipo en menos de 5 minutos en una máquina de escritorio razonable (hay algo de margen para esto; si toma unos minutos más en mi computadora portátil, no me importa, pero si toma 15, descalificaré eso).
Su solución se probará en varias cadenas diferentes que se enumeran a continuación. Su puntaje es el recuento total de bytes de los programas Starry correspondientes. En caso de empate, gana el metagolfer más corto. Es decir, no se moleste en jugar su propio código a menos que haya un empate (lo que creo que solo sucederá en el caso de que sea posible una solución óptima).
No debe optimizar su código para los casos de prueba específicos que se enumeran a continuación. Específicamente, no debe codificar soluciones hechas a mano para ellos. Está bien optimizar hacia clases de cadenas cuya estructura es similar a la de las cadenas dadas. Si sospecho que alguien tiene soluciones de codificación, me reservo el derecho de reemplazar algunos o todos los casos de prueba (con cadenas de estructuras comparables).
Casos de prueba
Cada línea es un caso de prueba separado:
Hello, World!
pneumonoultramicroscopicsilicovolcanoconiosis
.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.
Hickory, dickory, dock. The mouse ran up the clock. The clock struck 1. The mouse ran down. Hickory, dickory, dock.
36912059868043514648560046917066768694455682545071266675083273015450033938555319356951628735735013250100789433961153496780296165
bVZ48121347GLtpYnt76CZSxTpMDs6791EJE808077eySXldY162424ddTB90707UupwlWGb63618542VhA252989453TXrWgqGm85899uHOAY2oAKE198GOVUttvW63
7MYxoWBNt180CDHS5xBGvU70HHVB17bh8jYzIIiU6n6g98Rose1nOe8Svcg56nax20q30kT3Ttb2jHl5q2Iuf1vPbjPxm9cyKXwxc0OUK8pr13b2n7U9Y7RwQTc26A1I
n9}unwxVa}[rj+5em6K#-H@= p^X/:DS]b*Jv/_x4.a5vT/So2R`yKy=in7-15B=g _BD`Bw=Z`Br;UwwF[{q]cS|&i;Gn4)q=`!G]8"eFP`Mn:zt-#mfCV2AL2^fL"A
Los créditos para el segundo caso de prueba van a Dennis . Los créditos para el cuarto caso de prueba van a Sp3000.
Solución de referencia
Aquí hay una solución de referencia realmente básica en CJam:
q{S5*\iS*'+S'.}%
Puede ejecutarlo contra todo el conjunto de pruebas aquí. Los puntajes son:
1233
5240
4223
11110
7735
10497
11524
11392
Total: 62954
Es el enfoque más simple posible: empuje el punto de código de cada personaje como un literal y luego imprímalo. No hace uso de pequeñas diferencias entre caracteres consecutivos, impresión de enteros, partes repetitivas de la cadena, etc. Te dejaré esas cosas.
Creo que hay mucho margen de mejora. Como referencia, el más corto hecho a mano "Hello, World!" tiene solo 169 bytes de longitud.
JavaScript,
2515823778¡Ahora compatible con ES5!
Resultados:
Un buen comienzo en mi opinión, pero obviamente no ha terminado. En lugar de crear cada carácter por separado, agrega o resta del código de carácter anterior. Agregaré una explicación completa cuando termine el meta-golf.
fuente
charCodeAt
.