Escriba un programa que imprima la siguiente línea de 80 caracteres:
Este programa de codegolf.stackexchange.com se permuta para codificar una cadena.
luego acepta una línea de entrada, luego imprime su código fuente con sus puntos de código posiblemente reordenados (ninguno agregado y ninguno eliminado). Cuando se ejecuta ese código, tiene que suceder lo mismo, excepto que la línea impresa sería la línea de entrada más reciente.
La expresión regular de estilo Perl ^[A-Za-z0-9. ]{80}$
coincidirá con cualquier línea de entrada. No puede hacer ninguna suposición adicional.
El puntaje de una presentación es el número de puntos de código en su código fuente menos 94 . Más bajo es mejor.
El código no debe hacer nada que sea inaceptable en un quine ( por ejemplo , lectura de archivos). En particular, cualquier presentación con una puntuación negativa debe ser trampa de alguna manera, ¡como 93! es menor que 64 80 .
Agregado 2014-04-21: El código fuente completo de su programa debe estar bien formado en la codificación de caracteres bajo la cual cuenta los puntos de código. Por ejemplo, no puede usar 80 bytes consecutivos en el rango de bytes finales UTF-8 (80..BF) y contar cada uno como un solo CARACTER DE REEMPLAZO U + FFFD (o peor, como no es un punto de código).
Además, si la codificación permite múltiples formas de codificar un punto de código ( por ejemplo, SCSU ), su programa, así como todos los programas que genera directa o indirectamente, solo deben usar uno de ellos (o al menos todos deben ser tratados de manera equivalente en todo el código )
Respuestas:
GolfScript,
231162131Cómo funciona
Comenzamos eligiendo 94 caracteres diferentes que se permutarán para codificar una cadena. Cualquier 94 caracteres funcionaría, pero elegimos lo siguiente para jugar al golf:
Llamemos al conjunto de estos caracteres "&".
La línea de entrada siempre contendrá 81 caracteres (incluido el LF). Todos esos caracteres están presentes en los primeros 65 caracteres de "&". Esta es la única razón para elegir caracteres en los 128 bytes superiores.
Reemplazamos cada carácter de la cadena por su índice en "&", por lo que LF se convierte en 0, el espacio se convierte en 1, etc.
Consideramos que los 81 números obtenidos son los dígitos de un solo número base 65. Llamemos a este número "N".
Ahora, enumeramos todas las permutaciones posibles de "&" y recuperamos la permutación correspondiente al número de arriba. Esto se logra de la siguiente manera:
c = 1
yA = []
.N % c
aA
.N = N / c
yc = c + 1
.c < 95
, vuelve a 2.i = 0
ys = ""
.&[A[i]]
, agréguelo a "s" y quítelo de "&".i = i + 1
.i < 94
vuelve a 6.Supongamos que tenemos bloques de código "E" y "D" que codifican y decodifican una cadena como se explicó anteriormente.
Ahora, necesitamos un contenedor para esos bloques de código que cumpla con los requisitos de la pregunta:
Esto hace lo siguiente:
{…}.~
define un bloque, lo duplica y ejecuta la segunda copia. La primera copia permanecerá en la pila.\.$
intercambia la cadena codificada con el bloque y crea una copia de la cadena codificada, con caracteres ordenados.[{}/]:&;
convierte la cadena de arriba en una matriz, la guarda en "&" y la descarta.D puts
decodifica la cadena codificada e imprime el resultado.'"#{`head -1`}"'~
lee una línea de entrada ejecutandohead -1
en el shell.E "'".@+\+
codifica la cadena y antepone y agrega una comilla simple.\'.~'
intercambia la cadena codificada y el bloque y agrega la cadena'.~'
.Una vez ejecutado el bloque, GolfScript imprime el contenido de la pila (cadena codificada, bloque
'.~'
) y sale."E" se puede definir de la siguiente manera:
"D" se puede definir de la siguiente manera:
Golf final:
Reemplace
\.$[{}/]:&;0&@
con0@.$[{}/]:&\
para guardar dos caracteres.Defina la función
{;65base}:b
para guardar un personaje.Elimine todos los espacios en blanco excepto el LF final y el LF en la cadena.
Ejemplo
fuente
Perl,
14281099Tiene 1193 caracteres ASCII (incluidos 960 dígitos binarios permutados). 1193 - 94 = 1099
Mi primer diseño
Antes de tomar una sugerencia de Dennis para cambiar a binario, mi programa permutaba los dígitos octales.
Mi primer diseño codifica cada cadena en 160 dígitos octales, con 2 dígitos por carácter. Esta codificación tiene 100 8 = 64 caracteres diferentes. El sistema octal tiene 8 dígitos diferentes. El programa debe tener 160 copias de cada dígito, por lo que permuta 8 × 160 = 1280 dígitos.
Mantengo 160 dígitos
$s
y los otros 1120 dígitos$t
. Comienzo con un programa que no es una quine, sino que solo imprime las asignaciones para$s
y$t
para la próxima ejecución. Eso es todo:(() = $s =~ /$_/g))
es una asignación a una lista vacía de variables. Tomo este truco del tutorial de contexto en PerlMonks . Fuerza el contexto de la lista en el operador de coincidencia=~
. En contexto escalar, la coincidencia sería verdadera o falsa, y necesitaría un ciclo como$i++ while ($s =~ /$_/g)
para contar las coincidencias. En el contexto de la lista,$s =~ /$_/g
es una lista de coincidencias. Puse esta lista en el contexto escalar de una resta, por lo que Perl cuenta los elementos de la lista.Para hacer una quine, tomo el formulario
$_=q{print"\$_=q{$_};eval"};eval
de Perl quines en Rosetta Code . Éste asigna una cadenaq{...}
a$_
y luego llamaeval
, para que pueda tener mi código en una cadena y también ejecutarlo. Mi programa se convierte en una quine cuando envuelvo mi tercera y última línea en$_=q{
y};eval
, y cambio mi últimaprint
aprint "\$s = '$s';\n\$t = '$t';\n\$_=q{$_};eval"
.Finalmente, juego mi programa de golf cambiando la primera asignación
$t
a un comentario y eliminando caracteres adicionales.Tiene 1522 caracteres ASCII (incluidos 1280 dígitos octales permutados).
1522 - 94 = 1428
El cambio a binario
En los comentarios, Dennis notó que 960 dígitos binarios permutados serían menos de 1280 dígitos octales. Entonces graficé el número de dígitos permutados para cada base de 2 a 16.
Aunque la base 8 es un mínimo local, las bases 2 y 3 y 4 empatan para la mejor base, con 960 dígitos permutados. Para el código de golf, la base 2 es mejor porque Perl tiene conversiones para la base 2.
Reemplazar 1280 dígitos octales con 960 dígitos binarios ahorra 320 caracteres.
Cambiar el código de octal a binario cuesta 8 caracteres:
oct
aoct'0b'.$_
costos 7./../g
a/.{6}/g
costos 2."%02o"
a "% 06b" `cuesta 0.160
a480
costos 0.0..7
a0,1
guardados 1.Aprendí algunos consejos de golf de Perl . Guardan 14 caracteres:
'A'..'Z','a'..'z','0'..'9'
aA..Z,a..z,0..9
, usando palabras y números desnudos, guarda 12 caracteres."\n"
a$/
guardar 2 caracteres.Guardo 3 caracteres moviendo el
#$t
comentario al final del archivo. Esto elimina la nueva línea que finaliza el comentario y un literal\n
en la línea.Estos cambios ahorran un total de 329 caracteres y reducen mi puntaje de 1428 a 1099.
fuente