Interquine - Deux programmes qui se produisent en boucle


29

Le programme A génère le code du programme B lors de son exécution et B génère la source de A.

Exigences:

  • Une seule langue dans les deux programmes
  • Les programmes sont différents. Un programme qui sort lui-même n'est pas admissible.
  • Les deux programmes sont non vides ou d'une longueur d'au moins 1 octet. Les sauts de ligne à la fois dans la source et la sortie sont ignorés
  • stdin est fermé. Ne lisez rien ( vous ne pouvez donc pas lire la source et la manipuler). La sortie passe à stdout.
    Edit: stdin est connecté à /dev/null. Vous pouvez le commander fermé si clarifié.
  • N'utilisez pas de randomfonctions.

Additionnel:

  • Donner des explications si possible

Le score est la longueur totale . Le retour à la ligne ne compte pas s'il n'affecte pas le programme.



5
"N'utilisez pas de fonctions aléatoires."? Que voulez-vous dire? Des fonctions qui produisent un nombre aléatoire?
M. Xcoder du


Je suis sûr que vous ne voulez pas vraiment dire que stdin est fermé. Cela fait exploser certains environnements car stdin devient un doublon du premier fichier ouvert. Quoi qu'il en soit, si vous ne le corrigez pas, j'en abuserai.
Joshua

Réponses:


18

CJam , 13 + 13 = 26 octets

{sYZe\"_~"}_~

Essayez-le en ligne!

Les sorties

{sZYe\"_~"}_~

Explication

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

Puisque e\est commutatif dans ses deuxième et troisième opérandes, l'autre programme fait exactement la même chose, en échangeant Zet en Yretournant dans leur ordre d'origine.


17

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

"N^_p"
N^_p

Essayez-le en ligne!

Les sorties:

"N^_p
"
N^_p

La sortie a 13 octets, mais:

Le retour à la ligne ne compte pas s'il n'affecte pas le programme.

J'ai donc changé l'espace en une nouvelle ligne pour en profiter.

Il est basé sur la quine appropriée CJam la plus courte:

"_p"
_p

Et N^c'est de xor la chaîne avec un retour à la ligne, qui ajoute un retour à la ligne s'il n'y a pas de retour à la ligne, et le supprimer s'il y en a, pour une chaîne que chaque caractère est unique.

Je pense avoir vu ce quine dans la question de quine, mais je ne l'ai pas trouvé.


+1 pour avoir deux programmes de tailles différentes, contrairement à toutes les autres réponses jusqu'à présent. Edit: dès que je pourrai voter à nouveau .. atteint la limite du dernier vote>.>
Kevin Cruijssen

Bon pour être différent en longueur.
iBug

"Je pense que j'ai vu ce quine dans la question de quine, mais je ne l'ai pas trouvé." Il n'est mentionné que dans la réponse GolfScript.
Martin Ender

12

RProgN 2 , 3 + 3 = 6 octets

Premier programme:

0
1

Essayez-le en ligne!

Deuxième programme:

1
0

Essayez-le en ligne!

-2 merci à Martin Ender .


7
Vous pouvez économiser deux octets en changeant de langue: tio.run/##Kyooyk/P0zX6/9@Ay/D/fwA
Martin Ender

@MartinEnder Ooh à droite j'ai oublié que RProgN 2 présente un tel comportement ... btw je ne sais pas si c'est toujours ce buggy.
Erik the Outgolfer le

11
Je ne sais rien de RProgN, sauf que ce comportement existe.
Martin Ender

@MartinEnder Auteur de RProgN ici, demandez simplement si vous avez besoin de clarifier quoi que ce soit!
ATaco

@ATaco Eh bien, je vous aurais demandé de clarifier le downvote mais je ne pense pas que vous puissiez ...
Erik the Outgolfer

6

C, 95 + 95 = 190 octets

Merci à @immibis pour avoir économisé 16 * 2 octets!

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);}

Essayez-le en ligne!

Les sorties:

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);}

Essayez-le en ligne!

Quelles sorties:

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
Pourquoi ne pas simplement l'appeler C toujours et compter sur le changement pour rendre le programme différent? C est plus court que% c
user253751

@immibis Oui, vous avez raison, cela suffit parfaitement.
Steadybox

5

Javascript, 67 + 67 = 134 octets

1er programme:

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

2ème programme:

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

Ceci est basé sur la réponse d'Herman Lauenstein à Tri-interquine

Javascript (code source de lectures non valides), 75 + 75 = 150 61 + 61 = 122 58 + 58 = 116 50 + 50 = 100 octets

enregistré 20 octets grâce à Tushar, 6 octets grâce à Craig Ayre, et enregistré 16 octets grâce à kamoroso94

1er programme:

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

2ème programme:

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

Échange les 1 avec les 0 et vice versa. Ils font tous les deux la même chose, produisant simplement une sortie différente en raison de leur code source.


1
Économisons quelques octets. f.toString()=> (''+f), (0|1)=> 0|1, (a,b)=> arésultant enf=()=>("f="+(''+f).replace(/0|1/g,a=>a==0?1:0)+";f()");f()
Tushar

Vous pouvez utiliser un paramètre inutilisé pour enregistrer quelques octets f=_=>et supprimer les parens du rappel de remplacement comme l'a suggéré @Tushar:a=>+!+a
Craig Ayre

Remplacez "f="+(f+"")par ("f="+f)-3 octets.
kamoroso94

Remplacez /0|1/get /1|0/gpar 0et 1respectivement pour -5 octets.
kamoroso94

L'avez-vous exécuté? Cela fonctionne comme ça f=_=>alert(("f="+f).replace(0,a=>+!+a)+";f()");f().
kamoroso94

4

Python 2, 63 + 63 = 126 octets

Essayez-le en ligne

Premier programme:

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

les sorties:

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

Deuxième programme:

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

Les sorties:

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 octets

1:

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

2:

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

3

Mathematica, 43 + 44 = 87 octets

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

et

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

Testé sur mon ordinateur et la sortie du second n'a -1qu'à la fin, non -1 1.
numbermaniac

@numbermaniac J'ai écrit ces codes dans l'interface textuelle. Il semble qu'ils ne fonctionnent pas dans les cahiers.
alephalpha

3

asmutils sh, 16 + 16 octets, abusant de la règle "stdin est fermé".

#!/bin/sh
tr x y

Puisque stdin est fermé et sh ouvrira son script à la première poignée disponible (plutôt que de le déplacer vers une poignée numérotée comme le font les shells modernes), tr finit par lire une copie du script sans l'avoir jamais ouvert.

Cette interquine est capable de charge utile, mais l'insertion d'une charge utile est délicate.

De plus, cette version originale abuse d'un bug fou dans l'ancien noyau que j'utilisais à l'époque. (Je ne sais pas ce qui se passe avec ce noyau - j'ai découvert plus tard qu'il avait également des nombres majeurs et mineurs différents pour les périphériques.) Si vous corrigez les changements ABI qui ont cassé les composants, l'interquine ne fonctionnera toujours pas. J'oublie si asmutils sh a exec ou non, mais si c'est le cas, c'est une version moderne:

exec dd skip=0 | tr x y

Cela abuse d'un bug délibéré dans asmutils dd; il a une optimisation des performances qu'il appelle llseek pour sauter s'il le peut, mais pour enregistrer un octet, il passe SEEK_SET plutôt que SEEK_CUR. Il en résulte des ordures sur stderr mais l'interquine sur stdout. Asmutils dd n'a pas d'option pour supprimer le spam stderr.


Est-ce que cela fonctionnera si stdin est connecté à la /dev/nullplace? Quoi qu'il en soit, bon travail!
iBug

@iBug: Non. Dépend totalement de la fermeture de stdin et du fait que asmutils sh n'est pas lié à libc et n'hérite donc pas du code de réparation automatique dans libc.
Joshua

Avez-vous besoin du #!/bin/sh?
CalculatorFeline

@CalculatorFeline: cela dépend de l'exactitude de votre définition d'autre chose.
Joshua

En général, les shebangs ne sont pas comptés, ce serait donc 6 octets.
CalculatorFeline


1

Lisp commun, 58 caractères

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

... ou 24 caractères si cela ne vous dérange pas de supposer que la valeur *print-circle*globale est définie sur T:

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

La représentation imprimée du code est lue comme une structure cyclique, où #1#pointe vers la cellule suivante #1=. Nous citons des programmes pour qu'ils ne soient pas exécutés. Puisque *print-circle*c'est T, le REPL prend soin d'émettre de telles variables de lecteur lors de l'impression; voici ce que le code ci-dessus imprime et renvoie:

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

Lorsque nous évaluons le code ci-dessus, il imprime:

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

Si vous souhaitez vous en tenir à la valeur par défaut de *print-circle*, qui est NIL dans une implémentation conforme, vous devrez alors lier temporairement la variable:

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

À l'intérieur du corps du LET, nous imprimons les choses avec *print-circle*T. Nous obtenons donc:

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

Comme vous pouvez le voir, le nouveau programme ne se lie pas à nouveau *print-circle*, mais puisque nous utilisons write, qui est la fonction de bas niveau appelée par print, nous pouvons passer des arguments supplémentaires tels que :circle. Le code fonctionne alors comme prévu:

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

Cependant, vous devez exécuter les programmes ci - dessus comme un script, pas à l' intérieur d' un REPL, parce que même si vous imprimez des choses tout en prenant soin des structures circulaires, à la fois writeet printrenvoie également la valeur en cours d' impression; et dans un REPL par défaut, la valeur est également en cours d'impression, mais en dehors du contexte dynamique où *print-circle*est T.


1

> <> , 16 + 16 = 32 octets

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

et

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

Essayez-le en ligne!

Cela fonctionne en utilisant un saut dans le programme, le premier saut de programme sautera l'inverse de la pile (s'il inversait la pile, ce serait une quine). Le deuxième programme ne saute pas l'inverse, mais s'il était déjà inversé par le flux du programme, il créera l'original.

Ce code se terminera par une erreur.


1

RProgN 2 , 7 + 7 = 14 octets

Je voulais essayer de montrer une meilleure utilisation de RProgN, plutôt que de simplement abuser des commandes d'impression ...

1
«\1\-

et...

0
«\1\-

Expliqué

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.

Parce que cela imprime la pile à l'envers, la nouvelle constante est imprimée en premier, puis la version stringifed de la fonction est imprimée.

Essayez-le en ligne!


1

LOGO , 65 + 66 = 131 octets

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

et

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

1

Python 3, 74 + 74 = 148 octets

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

et

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

je ne le comprends pas non plus


1

> <> , 12 + 12 = 24 octets

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

et

':c-!|o|!*d3

Essayez-le en ligne!

Les deux programmes utilisent un littéral de chaîne d'encapsulation pour ajouter le code à la pile, puis produisent la 'commande via différentes méthodes. Lors de l'impression de la pile, il pousse le code vers l'arrière, mais le 'reste à l'avant. Il existe plusieurs variantes qui produisent le '; 3d*, d3*, 00g, :c-Lorsqu'il est associé avec 3d*et :9-quand il est associé avec 00g.

Une solution trop similaire pour poster, en Befunge-98 pour 13 * 2 octets

"2+ck, @,kc+2


0

Javascript (ES6), 36 + 36 = 72 octets

Programme 1:

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

Programme 2:

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

Ces programmes fonctionnent en se clonant et se remplacent 5par 4et 4avec5

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
Comme il s'agit de quine étiqueté , c'est ce qui serait généralement considéré comme un "quine de triche", car il lit sa propre source. Je ne sais pas quelle est la décision du PO à ce sujet, mais ils ne sont généralement pas autorisés.
Stephen

0

Klein , 26 24 octets

<:3+@+3<:"

Essayez-le en ligne!

Explication

Cela fonctionne de la même manière que mon Klein Quine , où il imprime la source à l'envers suivie d'un ", le dernier s'en est sorti en étant palindromique, donc tout ce que nous devons faire est de le rendre non palindromique sans endommager sa fonctionnalité. En changeant <et :nous avons pu le faire sans interférer avec les fonctionnalités.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.