Cotizaciones negativas mutuas

22

Esto fue inspirado por Print a Negative of your Code y Golf a mutine quine .


Considere un rectángulo de caracteres que cumpla con las siguientes restricciones:

  1. Consiste únicamente en caracteres ASCII imprimibles
  2. Dimensiones ambas mayores que 1
  3. Cada fila y cada columna contiene al menos un espacio.
  4. Cada fila y cada columna contiene al menos un carácter no espacial.

Por ejemplo, el siguiente es un rectángulo válido de 6x4:

%n 2e 
1  g 3
 &* __
 3  

Un negativo para este rectángulo se define como un rectángulo de dimensiones iguales, con todos los espacios reemplazados por caracteres no espaciales y todos los caracteres no espaciales reemplazados por espacios. Un negativo del rectángulo anterior podría ser:

  f  ^
 33 > 
9  $  
^ }|Q'

Se puede utilizar cualquier carácter ASCII que no se pueda imprimir en el espacio para reemplazar un espacio.

Tarea

Su tarea es escribir un programa con código fuente rectangular, que genere un negativo válido para sí mismo. El resultado negativo también debe ser un programa válido, en el mismo idioma que el original, y debe generar la fuente del original.

No se puede agregar o eliminar ningún espacio en blanco al final, a excepción de una nueva línea al final de cualquiera de las salidas, que es opcional.

Ningún programa puede leer el código fuente de ninguno de los dos; ni se pueden suponer entornos REPL.

Tanteo

Su puntaje es el producto de las dimensiones de su código (es decir, si su código fuente está en un rectángulo de 12 por 25, su puntaje es 12 * 15 = 180). Además, por cada carácter utilizado en un comentario, su puntaje aumenta en 2 (si usa /* .. */una vez en su código, y su código está en un rectángulo de 10 por 10, su puntaje sería 10 * 10 + 8 * 2 = 116).

El puntaje más bajo gana.

Si hay un empate, el envío con el menor número de espacios en el programa (ya sea el original o el negativo, el que tenga menos espacios) gana.

Si aún queda un empate, la respuesta anterior ganará.

Hay una bonificación de -52% , si la combinación de lo original y lo negativo produce una quine normal. Por ejemplo:

Original   Negative   Combined
 A A       B B        BABA
A A         B B       ABAB
es1024
fuente
@Optimizer Esa es la razón por la que no hice obligatorio el bono.
es1024
1
Estoy hablando solo de la parte negativa mutua quine;)
Optimizer
@ MartinBüttner Ah, mi mal. Estaba pensando en términos extraños.
Optimizador
1
¿Alguien puede hacer esto en c? ¡+1 a quien primero lo haga!
MegaTom

Respuestas:

15

CJam, ( 51 49 47 46 45 42 x 2) * 48% = 40.32

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 
                                         R

Ejecutar el código anterior da este resultado:

                                         R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 

ejecutando cual, imprime la fuente original.

La fuente y la salida son simplemente líneas intercambiadas.

Ahora viene la magia.

Superponiendo la fuente y los resultados de salida en el siguiente código:

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R

que es una quine perfecta!

Pruébalos en línea aquí


Cómo funciona

Toda la lógica de impresión está en la primera línea que maneja los tres casos explicados más adelante.

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~
{                                     }_~   "Copy this code block and execute the copy";
 ]                                          "Wrap everything before it in array";
  )                                         "Pop the last element out of it";
   "_~"+                                    "Append string '_~' to the copied code block";
        S41*                                "Create a string of 41 spaces";
            'R+                             "Append character R to it";
               @,                           "Rotate the array to top and get its length";
                 [{   }{   }{     }]=~      "Get the corresponding element from this"
                                            "array and execute it";

La matriz en la última línea anterior es la matriz que tiene bloques de código correspondientes a los tres casos.

Caso 1

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 
                                         R

En este caso, la longitud de la pila restante era 0, ya que cuando se ejecutó el bloque, solo tenía la copia del bloque en sí, que inicialmente apareció en el tercer paso anterior. Entonces sacamos el índice 0de la última matriz y lo ejecutamos:

 {N@S}          "Note that at this point, the stack is something like:"
                "[[<code block that was copied> '_ '~ ] <41 spaces and R string>]";
  N             "Add newline to stack";
   @            "Rotate the code block to top of stack";
    S           "Put a trailing space which negates the original R";

En este caso, la segunda línea es no operativa en lo que respecta a la impresión de la salida.

Caso 2

                                         R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 

En este caso, la pila ya contenía una cadena vacía, por lo que cuando se ejecutó el bloque de código copiado, tenía 2 elementos: una cadena vacía y el bloque de código en sí. Entonces sacamos el índice 1de la última matriz y lo ejecutamos:

{SN@}            "Note at this point, the stack is same as in case 1";
 SN              "Push space and newline to stack";
   @             "Rotate last three elements to bring the 41 spaces and R string to top";

Caso 3

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R

En este caso, la pila tiene 6 elementos. Entonces, después de hacer estallar el último bloque de código, la longitud restante de la matriz es 5. Tomamos el índice 5de la matriz y lo ejecutamos. (Tenga en cuenta que en una matriz de 3elementos, index 5es index 5%3 = 2)

{W=N]_}          "Note at this point, the stack is same as in case 1";
 W=              "Take the last character out of the 41 spaces and R string, i.e. R";
   N]            "Add a new line to stack and wrap the stack in an array";
     _           "Copy the array to get back the source of Case 3 itself";
Optimizador
fuente
27

Python, 97x2 + 2 = 196

No es una gran solución para comenzar, pero al menos funciona (creo).

c='o=1-%d;print("%%97s\\n%%97s"%%("#","c=%%r;exec(c%%%%%%d)\\40"%%(c,o),"#")[o:][:2])';exec(c%1) 
                                                                                                #

Salida:

                                                                                                #
c='o=1-%d;print("%%97s\\n%%97s"%%("#","c=%%r;exec(c%%%%%%d)\\40"%%(c,o),"#")[o:][:2])';exec(c%0) 
grc
fuente
8
+1 para la única presentación hasta ahora para usar un lenguaje real
WinnieNicklaus
Tampoco parece estar muy lejos de la bonificación.
mbomb007
23

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 -1si 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 0contrario, 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 10ve 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.";
Martin Ender
fuente
44
TLDR; voto a favor;)
Optimizer
¿No debería estar Y/2en la quine combinada?
schnaader
"Y por pura coincidencia" nah;)
Timtech
@Timtech Ver mi edición. La pura coincidencia no era un eufemismo. ^^
Martin Ender
10

CJam, 42 37 33 x 2 = 66

{`As_W%er"_~"+S 33*F'Lt1{\}*N\}_~
               L                 

que imprime

               L                 
{`As_W%er"_~"+S 33*F'Lt0{\}*N\}_~

(Las líneas se intercambian y se 1convierte en a 0.)

Pruébalo aquí.

Cómo funciona

Primero, debe comprender la quine básica de CJam:

{"_~"}_~

Las llaves simplemente definen un bloque de código, como una función, que no se ejecuta de inmediato. Si un bloque no ejecutado permanece en la pila, se imprime su código fuente (incluidas las llaves). _duplica el bloque y ~ejecuta la segunda copia. El bloque en sí mismo simplemente empuja la cadena que contiene _~. Entonces, este código deja la pila en el siguiente estado:

Stack: [{"_~"} "_~"]

El bloque y la cadena simplemente se imprimen consecutivamente al final del programa, lo que hace que esto sea una quine.

La belleza de esto es que podemos hacer lo que queramos en el bloque, y sigue siendo una quine, porque cada pieza de código se imprimirá automáticamente en el contenido del bloque. También podemos modificar el bloque, obteniendo su representación de cadena con `(que es solo una cadena del bloque con llaves).

Ahora veamos esta solución. Observe que cualquiera de las partes de la quine mutua contiene el bloque tipo quine con _~y an L. El Lempuja una cadena vacía en la pila, que no contribuye a la salida. Entonces, esto es lo que hace el bloque:

`                             "Convert block to its string representation.";
 As                           "Push 10 and convert to string.";
   _W%                        "Duplicate and reverse, to get another string 01.";
      er                      "Swap 0s and 1s in the block string.";
        "_~"+                 "Append _~.";
             S 33*            "Push a string with 33 spaces.";
                  F'Lt        "Set the character at index 15 to L.";
                      1{ }*   "Repeat this block once.";
                        \     "Swap the code string and the space string.";
                           N\ "Push a newline and move it between the two lines.";

Entonces esto hará la parte quine, pero intercambia un 1 por un 0, y también antepondrá otra línea con un L, donde el código anterior tiene un espacio. El problema es que el orden de esas dos líneas está determinado por el intercambio en el interior { }*. Y debido a que la parte externa de la quine mutua tiene el 0frente reemplazado por a 1, nunca ejecuta este intercambio y, por lo tanto, produce el orden original nuevamente.

Martin Ender
fuente
5

CJam, 27 × 2 = 54

{ ` " _ ~ " + N - ) 2 * ' '
 > @ t s G B + / N * } _ ~ 

Salida:

 { ` " _ ~ " + N - ) 2 * ' 
' > @ t s G B + / N * } _ ~

'A'B>compara los caracteres A y B. ' '\n >devuelve 1 porque 32> 10 y ' \n' >devuelve 0 porque los dos espacios son iguales.

jimmy23013
fuente
2

CJam, 30 29 x 2 = 58

{"_~"SN]_,4=S28*'R+\{N@}*}_~ 
                            R

Salidas:

                            R
{"_~"SN]_,4=S28*'R+\{N@}*}_~ 

que genera la fuente original.

Esto se basa en el mismo principio que mi otra solución.

Pruébalo en línea aquí

Optimizador
fuente