Mutui negativi Quines


22

Questo è stato ispirato da Print a Negative of your Code e Golf a mutual quine .


Considera un rettangolo di caratteri, che soddisfano le seguenti restrizioni:

  1. È costituito esclusivamente da caratteri ASCII stampabili
  2. Dimensioni entrambe maggiori di 1
  3. Ogni riga e ogni colonna contiene almeno uno spazio.
  4. Ogni riga e ogni colonna contiene almeno un carattere non spaziale.

Ad esempio, quanto segue è un rettangolo 6x4 valido:

%n 2e 
1  g 3
 &* __
 3  

Un negativo per questo rettangolo è definito come un rettangolo di uguali dimensioni, con tutti gli spazi sostituiti da caratteri non spaziali e tutti i caratteri non spaziali sostituiti da spazi. Un negativo del rettangolo sopra potrebbe essere:

  f  ^
 33 > 
9  $  
^ }|Q'

Qualsiasi carattere ASCII stampabile non spaziale può essere utilizzato per sostituire uno spazio.

Compito

Il tuo compito è quello di scrivere un programma con codice sorgente rettangolare, che produca un negativo valido per se stesso. Anche il risultato negativo deve essere un programma valido, nella stessa lingua dell'originale, e deve generare l'origine dell'originale.

Non è possibile aggiungere o rimuovere spazi vuoti finali, ad eccezione di una nuova riga finale finale alla fine di entrambi i risultati, che è facoltativa.

Nessuno dei due programmi è autorizzato a leggere il codice sorgente di nessuno dei due; né possono essere presupposti ambienti REPL.

punteggio

Il tuo punteggio è il prodotto delle dimensioni del tuo codice (cioè se il tuo codice sorgente è in un rettangolo 12 per 25, il tuo punteggio è 12 * 15 = 180). Inoltre, per ogni personaggio usato in un commento, il tuo punteggio aumenta di 2 (Se lo usi /* .. */una volta nel tuo codice e il tuo codice è in un rettangolo 10 per 10, il tuo punteggio sarebbe 10 * 10 + 8 * 2 = 116).

Vince il punteggio più basso.

Se c'è un pareggio, vince l'invio con il minor numero di spazi nel programma (sia l'originale che il negativo, a seconda di quale meno spazi).

Se rimane ancora un pareggio, vincerà la risposta precedente.

C'è un bonus del -52% , se la combinazione dell'originale e del negativo produce un quine normale. Per esempio:

Original   Negative   Combined
 A A       B B        BABA
A A         B B       ABAB

@Optimizer Questo è il motivo per cui non ho reso obbligatorio il bonus.
es1024,

1
Sto parlando solo della parte negativa reciproca;)
Ottimizzatore

@ MartinBüttner Ah, il mio male. Stavo pensando in termini strani.
Ottimizzatore

1
Qualcuno può farlo in c? +1 a chi lo farà per primo!
MegaTom,

Risposte:


15

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

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

L'esecuzione del codice precedente fornisce questo output:

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

in esecuzione, stampa la fonte originale.

La sorgente e l'output sono semplicemente linee scambiate.

Ora arriva la magia.

Sovrapponendo la sorgente e l'output si ottiene il seguente codice:

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

che è un quine perfetto!

Provali online qui


Come funziona

Tutta la logica di stampa è nella prima riga stessa che gestisce tutti e tre i casi spiegati in seguito.

{])"_~"+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";

L'array nell'ultima riga sopra è l'array che ha blocchi di codice corrispondenti a tutti e tre i casi.

Caso 1

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

In questo caso, la lunghezza dello stack rimanente era 0 come quando il blocco veniva eseguito, aveva solo la copia del blocco stesso, che era inizialmente spuntato nel terzo passaggio sopra. Quindi estraiamo l'indice 0dall'ultimo array ed eseguiamo:

 {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";

In questo caso, la seconda riga è no-op per quanto riguarda la stampa dell'output.

Caso 2

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

In questo caso, lo stack conteneva già una stringa vuota, quindi quando è stato eseguito il blocco di codice copiato, aveva 2 elementi: una stringa vuota e il blocco di codice stesso. Quindi estraiamo l'indice 1dall'ultimo array ed eseguiamo:

{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

In questo caso, lo stack ha 6 elementi. Quindi, dopo aver estratto l'ultimo blocco di codice, la lunghezza rimanente dell'array è 5. Estraggiamo l'indice 5dall'array e lo eseguiamo. (Nota che in una matrice di 3elementi, index 5è 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";

27

Python, 97x2 + 2 = 196

Non un'ottima soluzione per iniziare, ma almeno funziona (penso).

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

Produzione:

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

8
+1 per l'unica presentazione finora utilizzata per usare un linguaggio reale
WinnieNicklaus,

Non sembra essere troppo lontano dal bonus.
mbomb007

23

CJam, ( 58 56 54 48 46 x 2) * 48% = 44.16

{`"_~"+{_,94\m2/S*a_+\*                       
                       N/23f/Wf%N*}_`'"#)!*}_~

quale stampa

                       {`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~                       

I caratteri non spaziali in ciascuna riga rimangono gli stessi tra le due stringhe reciproche.

Ma ora la parte davvero dolce:

{`"_~"+{_,94\m2/S*a_+\*{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~N/23f/Wf%N*}_`'"#)!*}_~

è un quine! :)

Provalo qui.

Come funziona

Ti consiglio di leggere prima la spiegazione sull'altra mia presentazione, in quanto spiega le basi del quining in CJam in generale.

Questo è un po 'più complicato. Per il quine reciproco, come nell'altro caso, modifico la rappresentazione in forma di stringa del blocco aggiungendo spazi prima o dopo ogni riga e scambiando uno 0 con un 2, in modo che il programma risultante metta gli spazi all'estremità opposta.

Si noti che gli spazi non influiscono affatto sui reciproci quines. Nel primo, sono in un blocco, che non è realmente utilizzato, e nel secondo sono attorno all'intero codice.

Per ottenere un quine regolare quando si combinano entrambi, è necessario trovare un modo per evitare di apportare tutte queste modifiche. Si noti che la struttura dello spazio bianco e del codice significa che combinando entrambi, inseriamo l'intero quine nell'altro. Quindi, se inseriamo l'intero codice di modifica in un blocco, possiamo eseguire quel blocco in base al suo contenuto effettivo.

Quindi ora ho questo blocco ... per le quine reciproche, contiene solo il codice che in realtà voglio eseguire. Per il quine combinato, contiene anche di nuovo l'intero quine, in una posizione casuale, il che non ha alcun senso ... ma poiché è un blocco, non viene eseguito automaticamente. Quindi possiamo determinare se modificare la stringa in base al contenuto di quel blocco. Questo è ciò che _`'"#)!serve. Duplica il blocco, lo converte in una stringa, cerca il carattere "(che, nelle stringhe reciproche, appare solo all'esterno del blocco) - la ricerca ritorna -1se il carattere non viene trovato e un intero positivo altrimenti -, incrementa il risultato e lo nega logicamente. Quindi, se è "stato trovato un, questo produce 0altrimenti 1. Adesso lo facciamo e basta*, che esegue il blocco una volta, se il risultato era 1 e per niente altrimenti.

Infine, ecco come funziona il codice di modifica:

_,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.";

Rivendicazione della taglia, (12 x 10) * 48% = 57.6

Si scopre che questo codice può essere suddiviso su più righe molto facilmente con alcune modifiche. Aggiungiamo 2 caratteri, per ottenere 48 di fila, che possiamo quindi dividere convenientemente per 8, in modo da avere 8 righe con 6 caratteri di codice e 6 spazi. Per fare ciò dobbiamo anche cambiare alcuni numeri e riorganizzare uno o due operatori, in modo che non vengano suddivisi su entrambe le righe. Questo ci dà una versione funzionante con dimensioni 12 x 8 ... una tantum. Quindi aggiungiamo solo due righe che non fanno nulla (premi un 1, fai scoppiare un 1, premi un 1, fai scoppiare un 1 ...), quindi arriva a 12 x 10 :

{`"_~"      
      +{129X
$,m2/S      
      *a_+\*
N/6f/1      
      ;1;1;1
;1;1;1      
      ;Wf%N*
}_`'"#      
      )!*}_~

Come il precedente questo produce

      {`"_~"
+{129X      
      $,m2/S
*a_+\*      
      N/6f/1
;1;1;1      
      ;1;1;1
;Wf%N*      
      }_`'"#
)!*}_~      

(Nota a margine: non è necessario continuare a alternare sinistra e destra sulle linee intermedie, solo la posizione della prima e dell'ultima linea sono importanti. Sinistra e destra possono essere scelte arbitrariamente per tutte le altre linee.)

E per pura coincidenza, anche il quine completo funziona ancora:

{`"_~"{`"_~"
+{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*
}_`'"#}_`'"#      
)!*}_~)!*}_~

(Dico una coincidenza, perché la parte che si occupa di non eseguire il codice interno ora viene stranamente intervallata dall'altra quina, ma sembra comunque funzionare bene.)

Detto questo, avrei potuto aggiungere 44 righe 1;alla mia presentazione originale per soddisfare il requisito di generosità, ma 12 x 10sembra molto più ordinato. ;)

Edit: Haha, quando ho detto "pura coincidenza" non avrei potuto essere più esatto. Ho esaminato il modo in cui ora funziona il quine finale, ed è assolutamente ridicolo. Esistono tre blocchi nidificati (4 in realtà, ma il più interno è irrilevante). L'unica parte importante del più interno di quei 3 blocchi è che contiene un "(e non quello che ha fatto nella presentazione originale, ma proprio '"quello usato alla fine per verificare lo stesso personaggio). Quindi la struttura di base del quine è:

{`"_~"{`"_~"+{___'"___}_`'"#)!*}_~)!*}_~

Analizziamo che:

{`"_~"                               }_~ "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.";

Quindi questo fa davvero qualche magia divertente, ma poiché il blocco interno lascia una singola stringa in pila, )!*sembra trasformarla in una stringa vuota. L'unica condizione è che le cose nel blocco interno dopo +non facciano altro nello stack, quindi diamo un'occhiata a questo:

             {___'"___}                  "Push a block which happens to contain 
                                          quotes.";
                       _`'"#)!*          "This is from the original code and just 
                                          removes the block if it does contain 
                                          quotes.";

4
TLDR; voto positivo;)
Ottimizzatore

Non dovrebbe essere Y/2nel quine combinato?
Schnaader,

"E per pura coincidenza" nah;)
Timtech,

@Timtech Vedi la mia modifica. La pura coincidenza non era un eufemismo. ^^
Martin Ender,

10

CJam, 42 37 33 x 2 = 66

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

quale stampa

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

(Le linee vengono scambiate e una 1si trasforma in a 0.)

Provalo qui.

Come funziona

Innanzitutto, dovresti capire il quine CJam di base:

{"_~"}_~

Le parentesi graffe definiscono semplicemente un blocco di codice, come una funzione, che non viene immediatamente eseguita. Se un blocco non eseguito rimane nello stack, viene stampato il suo codice sorgente (comprese le parentesi graffe). _duplica il blocco ed ~esegue la seconda copia. Il blocco stesso spinge semplicemente la stringa contenente _~. Quindi questo codice lascia lo stack nel seguente stato:

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

Il blocco e la stringa sono semplicemente stampati back-to-back alla fine del programma, il che rende questo un quine.

Il bello di questo è che possiamo fare quello che vogliamo nel blocco, e rimane un quine, perché ogni pezzo di codice verrà automaticamente stampato nel contenuto del blocco. Possiamo anche modificare il blocco, ottenendo la sua rappresentazione di stringa con `(che è solo una stringa del blocco con parentesi graffe).

Ora diamo un'occhiata a questa soluzione. Si noti che una delle parti del quine reciproco contiene il blocco simile al quine con _~e un L. Il Lspinge una stringa vuota in pila, che non contribuisce alla produzione. Quindi, ecco cosa fa il blocco:

`                             "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.";

Quindi questo farà la parte quine, ma scambia un 1 con uno 0 e antepone un'altra riga con un L, dove il codice sopra ha uno spazio. Il problema è che l'ordine di quelle due linee è determinato dallo scambio all'interno { }*. E poiché la parte esterna del quine reciproco ha la parte 0frontale sostituita da una 1, non esegue mai questo scambio e quindi produce di nuovo l'ordine originale.


5

CJam, 27 × 2 = 54

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

Produzione:

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

'A'B>confronta i caratteri A e B. ' '\n >restituisce 1 perché 32> 10 e ' \n' >restituisce 0 perché i due spazi sono uguali.


2

CJam, 30 29 x 2 = 58

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

Uscite:

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

che genera la fonte originale.

Questo si basa sullo stesso principio della mia altra soluzione.

Provalo online qui

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.