Interquine - Due programmi che si generano a vicenda in un ciclo


29

Il programma A emette il codice del programma B quando viene eseguito e B emette la sorgente A.

Requisiti:

  • Solo una lingua per entrambi i programmi
  • I programmi sono diversi. Un programma che genera se stesso non si qualifica.
  • Entrambi i programmi sono non vuoti o lunghi almeno 1 byte. Le nuove righe finali sia in sorgente che in output vengono ignorate
  • stdin è chiuso. Non leggere nulla (quindi non puoi leggere la fonte e manipolarla). L'output va allo stdout.
    Modifica: stdin è collegato a /dev/null. È possibile ordinare che sia chiuso se chiarito.
  • Non utilizzare le randomfunzioni.

Ulteriori:

  • Dare spiegazioni se possibile

Il punteggio è la lunghezza totale . Il trascinamento di newline non conta se non influisce sul programma.



5
"Non utilizzare funzioni casuali."? Cosa intendi? Funzioni che producono un numero casuale?
Mr. Xcoder,


Sono abbastanza sicuro che non intendi davvero che stdin sia chiuso. Questo fa esplodere alcuni ambienti poiché stdin diventa un duplicato del primo file aperto. Comunque, se non lo aggiusti, lo abuserò.
Giosuè,

Risposte:


18

CJam , 13 + 13 = 26 byte

{sYZe\"_~"}_~

Provalo online!

Uscite

{sZYe\"_~"}_~

Spiegazione

{       e# Standard quine framework, leaves a copy of the block on the stack
        e# for the block itself to process.
  s     e# Stringify the block.
  YZe\  e# Swap the characters at indices 2 and 3, which are Y and Z themselves.
  "_~"  e# Push the "_~" to complete the quine.
}_~

Dal momento che e\è commutativo nel suo secondo e terzo operando, l'altro programma fa esattamente lo stesso, scambiando Ze di Ynuovo nel loro ordine originale.


17

CJam ,11 + 13 = 24 11 + 12 = 23 byte

"N^_p"
N^_p

Provalo online!

Uscite:

"N^_p
"
N^_p

L'output ha 13 byte, ma:

Il trascinamento di newline non conta se non influisce sul programma.

Quindi ho cambiato lo spazio in una nuova riga per trarne vantaggio.

Si basa sul quine proprio CJam più corto:

"_p"
_p

E N^ è xor la stringa con una nuova riga, che aggiunge una nuova riga se non c'è una nuova riga e rimuoverla se esiste, per una stringa che ogni carattere è unico.

Penso di aver visto quel quine nella domanda quine, ma non sono riuscito a trovarlo.


+1 per avere due programmi di dimensioni diverse, a differenza di tutte le altre risposte finora. Modifica: appena posso votare di nuovo .. ha raggiunto il limite ultimo voto>.>
Kevin Cruijssen

Buono per essere diverso in lunghezza.
iBug

"Penso di aver visto quel quine nella domanda quine, ma non sono riuscito a trovarlo." È menzionato solo nella risposta GolfScript.
Martin Ender,

12

RProgN 2 , 3 + 3 = 6 byte

Primo programma:

0
1

Provalo online!

Secondo programma:

1
0

Provalo online!

-2 grazie a Martin Ender .


7
È possibile salvare due byte cambiando lingua: tio.run/##Kyooyk/P0zX6/9@Ay/D/fwA
Martin Ender

@MartinEnder Ooh giusto, ho dimenticato che RProgN 2 mostra un simile comportamento ... tra l'altro non so se è ancora quel buggy.
Erik the Outgolfer,

11
Non so nulla di RProgN se non che questo comportamento esiste.
Martin Ender,

@MartinEnder Autore di RProgN qui, basta chiedere se hai bisogno di chiarimenti!
ATaco,

@ATaco Beh, ti avrei chiesto di chiarire il downvote ma non credo che tu possa ...
Erik the Outgolfer,

6

C, 95 + 95 = 190 byte

Grazie a @immibis per aver salvato 16 * 2 byte!

char*s="char*s=%c%s%c;main(i){i=%d^1;printf(s,34,s,34,i);}";main(i){i=1^1;printf(s,34,s,34,i);}

Provalo online!

Uscite:

char*s="char*s=%c%s%c;main(i){i=%d^1;printf(s,34,s,34,i);}";main(i){i=0^1;printf(s,34,s,34,i);}

Provalo online!

Quali uscite:

char*s="char*s=%c%s%c;main(i){i=%d^1;printf(s,34,s,34,i);}";main(i){i=1^1;printf(s,34,s,34,i);}

1
Perché non chiamarlo sempre C e fare affidamento sul fatto che sto cambiando per rendere il programma diverso? C è inferiore a% c
user253751 il

@immibis Sì, hai ragione, è sufficiente.
Steadybox,

5

Javascript, 67 + 67 = 134 byte

1o programma:

alert(eval(c="`alert(eval(c=${JSON.stringify(c)},n=${+!n}))`",n=0))

2o programma:

alert(eval(c="`alert(eval(c=${JSON.stringify(c)},n=${+!n}))`",n=1))

Questo si basa sulla risposta di Herman Lauenstein a Tri-interquine

Javascript (codice sorgente di letture non valide), 75 + 75 = 150 61 + 61 = 122 58 + 58 = 116 50 + 50 = 100 byte

salvato 20 byte grazie a Tushar, 6 byte grazie a Craig Ayre e salvato 16 byte grazie a kamoroso94

1o programma:

f=_=>alert(("f="+f).replace(0,a=>+!+a)+";f()");f()

2o programma:

f=_=>alert(("f="+f).replace(1,a=>+!+a)+";f()");f()

Scambia gli 1 con gli 0 e viceversa. Entrambi fanno la stessa cosa, producendo solo output diversi a causa del loro codice sorgente.


1
Salviamo pochi byte. f.toString()=> (''+f), (0|1)=> 0|1, (a,b)=> arisultante inf=()=>("f="+(''+f).replace(/0|1/g,a=>a==0?1:0)+";f()");f()
Tushar,

È possibile utilizzare un parametro inutilizzato per salvare un paio di byte f=_=>e rimuovere le parentesi dal callback di sostituzione come suggerito da @Tushar:a=>+!+a
Craig Ayre,

Sostituire "f="+(f+"")con ("f="+f)-3 byte.
kamoroso94,

Sostituisci /0|1/ge /1|0/gcon 0e 1rispettivamente per -5 byte.
kamoroso94,

L'hai eseguito? Funziona così f=_=>alert(("f="+f).replace(0,a=>+!+a)+";f()");f().
kamoroso94,

4

Python 2, 63 + 63 = 126 byte

Provalo online

Primo programma:

A='A=%r;print A[:23]%%A+A[29:35]23:29]';print A[:23]%A+A[23:29]

uscite:

A='A=%r;print A[:23]%%A+A[29:35]23:29]';print A[:23]%A+A[29:35]

Secondo programma:

A='A=%r;print A[:23]%%A+A[29:35]23:29]';print A[:23]%A+A[29:35]

Uscite:

A='A=%r;print A[:23]%%A+A[29:35]23:29]';print A[:23]%A+A[23:29]

4

JavaScript ( JsShell ), 35 + 34 = 69 byte

1:

(f=x=>print(`(f=${f})(${-x})`))(-1)

2:

(f=x=>print(`(f=${f})(${-x})`))(1)

3

Mathematica, 43 + 44 = 87 byte

(Print[#1[#0[#1, -#2]]] & )[HoldForm, -1 1]

e

(Print[#1[#0[#1, -#2]]] & )[HoldForm, -(-1)]

L'ho provato sul mio computer e l'output del secondo ha solo -1alla fine, no -1 1.
numbermaniac,

@numbermaniac Ho scritto questi codici nell'interfaccia testuale. Sembra che non funzionino nei notebook.
alephalpha,

3

asmutils sh, 16 + 16 byte, abusando della regola "stdin is closed".

#!/bin/sh
tr x y

Poiché stdin è chiuso e sh aprirà il suo script al primo handle disponibile (anziché spostarlo in un handle numerato alto come fanno le shell moderne), tr finisce per leggere da una copia dello script senza averlo mai aperto.

Questo interquino è capace di payload ma l'inserimento di un payload è complicato.

Inoltre, questa versione originale abusa di alcuni bug pazzi nell'antico kernel che ho usato in quei giorni. (Non so cosa succede con quel kernel - ho scoperto in seguito che aveva anche numeri maggiori e minori diversi per i dispositivi.) Se correggete le modifiche ABI che hanno rotto i problemi, l'interquino continuerà a non funzionare. Dimentico se asmutils sh ha exec o no, ma se lo fa, questa è una versione moderna:

exec dd skip=0 | tr x y

Questo abusa di un errore deliberato in asmutils dd; ha un'ottimizzazione delle prestazioni che chiama llseek per saltare se può, ma per salvare un byte passa SEEK_SET anziché SEEK_CUR. Ciò si traduce in immondizia su stderr ma l'interquino su stdout. Asmutils dd non ha un'opzione per sopprimere lo spam stderr.


Funzionerà se lo stdin è collegato /dev/nullinvece? Comunque, buon lavoro!
iBug,

@iBug: No. Dipende completamente dallo stdin chiuso e dal fatto che asmutils sh non è collegato a libc e quindi non eredita il codice di riparazione automatica in libc.
Giosuè,

Ti serve il #!/bin/sh?
CalculatorFeline

@CalculatorFeline: dipende dall'esattezza della tua definizione di qualcos'altro.
Giosuè,

Generalmente, i shebang non vengono conteggiati, quindi questo sarebbe di 6 byte.
Calcolatrice


1

Lisp comune, 58 caratteri

#1=(let((*print-circle* t))(print'(write '#1# :circle t)))

... o 24 caratteri se non ti dispiace supporre che *print-circle*sia globalmente impostato su T:

#1=(print '(write '#1#))

La rappresentazione stampata del codice viene letta come una struttura ciclica, in cui #1#punta di nuovo alla cella contro #1=. Citiamo i programmi in modo che non vengano eseguiti. Poiché *print-circle*è T, REPL si occupa di emettere tali variabili di lettore durante la stampa; questo è ciò che stampa il codice sopra e restituisce:

#1=(write '(print '#1#)) 

Quando valutiamo il codice sopra, stampa:

#1=(print '(write '#1#))

Se si desidera mantenere il valore predefinito per *print-circle*, che è NIL in un'implementazione conforme, sarà necessario ricollegare temporaneamente la variabile:

#1=(let((*print-circle* t))(print'(write '#1# :circle t)))

All'interno del corpo della LET, stampiamo le cose con l' *print-circle*essere T. Quindi otteniamo:

#1=(write
    '(let ((*print-circle* t))
       (print '#1#))
    :circle t) 

Come puoi vedere, il nuovo programma non si ricollega *print-circle*, ma poiché stiamo usando write, che è la funzione di basso livello chiamata da print, possiamo passare argomenti aggiuntivi come :circle. Il codice funziona quindi come previsto:

#1=(let ((*print-circle* t))
     (print '(write '#1# :circle t)))

Tuttavia, è necessario eseguire i programmi sopra indicati come script, non all'interno di un REPL, perché anche se si stampano cose mentre si prendono cura delle strutture circolari, entrambi writee printrestituiscono anche il valore in fase di stampa; e in una REPL predefinita, viene anche stampato il valore, ma al di fuori del contesto dinamico in cui *print-circle*è T.


1

> <> , 16 + 16 = 32 byte

":1-}80.r   !#o#

e

#o#!   r.08}-1:"

Provalo online!

Funziona usando un salto nel programma, i primi programmi salteranno il contrario dello stack (se invertisse lo stack sarebbe un quine). Il secondo programma non salta il contrario ma era già invertito dal flusso del programma, quindi creerà l'originale.

Questo codice terminerà con un errore.


1

RProgN 2 , 7 + 7 = 14 byte

Volevo provare a mostrare un uso migliore di RProgN, piuttosto che abusare degli ordini di stampa ...

1
«\1\-

e...

0
«\1\-

spiegato

1   # Push the constant, 1. (Or 0, depending on the program)

«\1\-
«       # Define a function from this to the matching », in this case there isn't any, so define it from this to the end of the program, then continue processing.
 \      # Flip the defined function under the constant.
  1\-   # Get 1 - Constant.

Poiché questo stampa la pila capovolta, viene stampata prima la nuova costante, quindi viene stampata la versione con stringhe della funzione.

Provalo online!


1

LOGO , 65 + 66 = 131 byte

apply [(pr ? ` [[,? ,-?2]] )] [[apply [(pr ? ` [[,? ,-?2]] )]] 1]

e

apply [(pr ? ` [[,? ,-?2]] )] [[apply [(pr ? ` [[,? ,-?2]] )]] -1]

1

Python 3, 74 + 74 = 148 byte

a='a=%r;b=%r;print(b%%(b,a))';b='b=%r;a=%r;print(a%%(a,b))';print(b%(b,a))

e

b='b=%r;a=%r;print(a%%(a,b))';a='a=%r;b=%r;print(b%%(b,a))';print(a%(a,b))

non lo capisco neanche io


1

> <> , 12 + 12 = 24 byte

'3d*!|o|!-c:

e

':c-!|o|!*d3

Provalo online!

Entrambi i programmi usano una stringa di wrapping letterale per aggiungere il codice allo stack, quindi produrre il file ' comando con metodi diversi. Quando si stampa la pila, il codice viene spostato all'indietro, tuttavia 'rimane nella parte anteriore. Esistono diverse varianti che producono il '; 3d*,d3* , 00g, :c-Se abbinato con 3d*e :9-se abbinato con 00g.

A troppo soluzione simile alla posta, in Befunge-98 per 13 * 2 byte

"2+ck, @,kc+2


0

Javascript (ES6), 36 + 36 = 72 byte

Programma 1:

f=n=>('f='+f).replace(/4|5/g,n=>n^1)

Programma 2:

f=n=>('f='+f).replace(/5|4/g,n=>n^1)

Questi programmi funzionano clonando se stessi e sostituendo 5con 4e 4con5

console.log((
    f=n=>('f='+f).replace(/4|5/g,n=>n^1)
)())
console.log((
    f=n=>('f='+f).replace(/5|4/g,n=>n^1)
)())


2
Dal momento che questo è etichettato quine , questo è quello che sarebbe generalmente considerato un "cheat quine", dal momento che legge la propria fonte. Non sono sicuro di quale sia la decisione di OP in merito, ma di solito non sono ammessi.
Stephen,

0

Klein , 26 24 byte

<:3+@+3<:"

Provalo online!

Spiegazione

Funziona allo stesso modo del mio Klein Quine , dove stampa la fonte all'indietro seguita da una ", l'ultima se ne è andata diventando palindromica, quindi tutto ciò che dobbiamo fare è renderlo non palindromico senza danneggiarne la funzionalità. Passando <e :siamo riusciti a farlo senza interferire con la funzionalità.


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.