CJam, ( 58 56 54 48 46 x 2) * 48% = 44.16
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
que imprime
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
Los caracteres no espaciales en cada línea permanecen iguales entre las dos líneas mutuas.
Pero ahora la parte realmente dulce:
{`"_~"+{_,94\m2/S*a_+\*{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~N/23f/Wf%N*}_`'"#)!*}_~
es una quine! :)
Pruébalo aquí.
Cómo funciona
Le recomiendo que primero lea la explicación en mi otro envío, ya que explica los conceptos básicos de las citas en CJam en general.
Este es un poco más complicado. Para la quine mutua, como en el otro caso, modifico la representación de cadena del bloque agregando espacios antes o después de cada línea, e intercambiando un 0 con un 2, para que el programa resultante coloque los espacios en el extremo opuesto.
Tenga en cuenta que los espacios no afectan a las quines mutuas en absoluto. En el primero, están en un bloque, que no se usa realmente, y en el segundo están alrededor del código completo.
Para obtener una quine regular al combinar ambos, necesitamos encontrar una manera de evitar hacer toda esa modificación. Tenga en cuenta que la estructura del espacio en blanco y el código significa que al combinar ambos, insertamos la totalidad de una quine en la otra. Entonces, si ponemos el código de modificación completo en un bloque, podemos ejecutar ese bloque dependiendo de su contenido real.
Así que ahora tengo este bloque ... para las cuotas mutuas, solo contiene el código que realmente quiero ejecutar. Para la quine combinada, también contiene la quine entera nuevamente, en una posición aleatoria, lo que no tiene ningún sentido ... pero como es un bloque, no se ejecuta automáticamente. Por lo tanto, podemos determinar si se modifica la cadena en función del contenido de ese bloque. Para eso _`'"#)!
es eso . Duplica el bloque, lo convierte en una cadena, busca el carácter "
(que, en las mutuas, solo aparece fuera del bloque), la búsqueda regresa -1
si no se encuentra el carácter y un entero positivo de lo contrario, incrementa el resultado y lo niega lógicamente. Entonces, si "
se encontró un, esto produce lo 0
contrario, rinde 1
. Ahora solo hacemos*
, que ejecuta el bloque una vez, si el resultado fue 1 y nada de lo contrario.
Finalmente, así es como funciona el código de modificación:
_,94\m2/S*a_+\*N/23f/Wf%N*
_, "Duplicate the quine string and get its length.";
94\m "Subtract from 94.";
2/ "Divide by two.";
S* "Create a string with that many spaces. This will be
an empty string for the first mutual quine, and contain
23 spaces for the second mutual quine.";
a_+ "Create an array that contains this string twice.";
\* "Join the two copies together with the quine string.";
N/ "Split into lines.";
23f/ "Split each line into halves (23 bytes each).";
Wf% "Reverse the two halves of each line.";
N* "Join with a newline.";
Reclamando la recompensa, (12 x 10) * 48% = 57.6
Resulta que este código se puede dividir en más líneas muy fácilmente con algunas modificaciones. Agregamos 2 caracteres, para obtener 48 en una fila, que luego podemos dividir convenientemente entre 8, para que tengamos 8 líneas con 6 caracteres de código y 6 espacios. Para hacer eso, también necesitamos cambiar algunos números y reorganizar un operador o dos, para que no se dividan en ambas líneas. Eso nos da una versión funcional con un tamaño de 12 x 8 ... uno fuera del requisito. Así que solo agregamos dos líneas que no hacen nada (presionar un 1, pop a 1, presionar un 1, pop a 1 ...), así que llegue a 12 x 10 :
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
Como el anterior esto produce
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
(Nota al margen: no hay necesidad de alternar a la izquierda y a la derecha en las líneas intermedias, solo la posición de la primera y la última línea es importante. La izquierda y la derecha se pueden elegir arbitrariamente para todas las demás líneas).
Y por pura coincidencia, la quine completa todavía funciona:
{`"_~"{`"_~"
+{129X+{129X
$,m2/S$,m2/S
*a_+\**a_+\*
N/6f/1N/6f/1
;1;1;1;1;1;1
;1;1;1;1;1;1
;Wf%N*;Wf%N*
}_`'"#}_`'"#
)!*}_~)!*}_~
(Digo coincidencia, porque la parte que se encarga de no ejecutar el código interno ahora se intercala extrañamente con la otra quine, pero aún así funciona bien).
Dicho esto, podría haber agregado 44 líneas 1;
a mi presentación original para cumplir con el requisito de recompensa, pero se 12 x 10
ve mucho más ordenado. ;)
Editar: Jaja, cuando dije "pura coincidencia" no podría haber sido más acertado. Investigué cómo funciona actualmente la quine final, y es absolutamente ridículo. Hay tres bloques anidados (4 en realidad, pero el más interno es irrelevante). La única parte importante del más interno de esos 3 bloques es que contiene un "
(y no el que hizo en el envío original, sino el '"
que se usa al final para verificar el mismo carácter). Entonces, la estructura básica de la quine es:
{`"_~"{`"_~"+{___'"___}_`'"#)!*}_~)!*}_~
Vamos a diseccionar eso:
{`"_~" }_~ "The standard CJam quine.";
{`"_~"+ }_~ "Another CJam quine. Provided it doesn't do
anything in the rest of that block, this
will leave this inner block as a string on
the stack.";
) "Slice the last character off the string.";
! "Negate... this yields 0.";
* "Repeat the string zero times.";
Entonces, esto realmente hace algo de magia divertida, pero debido a que el bloque interno deja una sola cadena en la pila, )!*
pasa a convertirla en una cadena vacía. La única condición es que las cosas en el bloque interno después +
no hagan nada más a la pila, así que veamos eso:
{___'"___} "Push a block which happens to contain
quotes.";
_`'"#)!* "This is from the original code and just
removes the block if it does contain
quotes.";