CJam, ( 58 56 54 48 46 x 2) * 48% = 44,16
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
qui imprime
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
Les caractères non-espace dans chaque ligne restent les mêmes entre les deux quines mutuelles.
Mais maintenant, la partie vraiment douce:
{`"_~"+{_,94\m2/S*a_+\*{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~N/23f/Wf%N*}_`'"#)!*}_~
est une quine! :)
Testez-le ici.
Comment ça marche
Je vous recommande de lire d'abord l'explication de mon autre soumission, car elle explique les bases du quining dans CJam en général.
Celui-ci est un peu plus délicat. Pour le quine mutuel, comme dans l'autre cas, je modifie la représentation sous forme de chaîne du bloc en ajoutant des espaces avant ou après chaque ligne, et en échangeant un 0 avec un 2, de sorte que le programme résultant place les espaces à l'extrémité opposée.
Notez que les espaces n'affectent pas du tout les quines mutuelles. Dans le premier, ils sont dans un bloc, qui n'est pas vraiment utilisé, et dans le second, ils sont autour du code entier.
Pour obtenir une quine régulière lors de la combinaison des deux, nous devons trouver un moyen d'éviter de faire toute cette modification. Notez que la structure des espaces et du code signifie qu'en combinant les deux, nous insérons l'intégralité d'une quine dans l'autre. Donc, si nous mettons le code de modification entier dans un bloc, nous pouvons exécuter ce bloc en fonction de son contenu réel.
Alors maintenant, j'ai ce bloc ... pour les quines mutuelles, il ne contient que le code que je veux réellement exécuter. Pour le quine combiné, il contient également à nouveau le quine entier, dans une position aléatoire, ce qui n'a aucun sens ... mais comme c'est un bloc, il n'est pas exécuté automatiquement. Nous pouvons donc déterminer s'il faut modifier la chaîne en fonction du contenu de ce bloc. C'est pour ça _`'"#)!
. Il duplique le bloc, le convertit en chaîne, recherche le caractère "
(qui, dans les quines mutuelles, n'apparaît qu'en dehors du bloc) - la recherche retourne -1
si le caractère n'est pas trouvé et un entier positif sinon -, incrémente le résultat et le nie logiquement. Donc, si un a "
été trouvé, cela donne 0
sinon il donne 1
. Maintenant on fait juste*
, qui exécute le bloc une fois, si le résultat était 1 et pas du tout autrement.
Enfin, voici comment fonctionne le code de modification:
_,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.";
Réclamant la prime, (12 x 10) * 48% = 57,6
Il s'avère que ce code peut être divisé sur plusieurs lignes très facilement avec quelques modifications. Nous ajoutons 2 caractères, pour obtenir 48 de suite, que nous pouvons ensuite facilement diviser par 8, de sorte que nous avons 8 lignes avec 6 caractères de code et 6 espaces. Pour ce faire, nous devons également modifier quelques chiffres et réorganiser un ou deux opérateurs afin qu'ils ne soient pas répartis sur les deux lignes. Cela nous donne une version de travail avec une taille 12 x 8 ... une sur l'exigence. Nous ajoutons donc simplement deux lignes qui ne font rien (poussez un 1, poussez un 1, poussez un 1, piquez un 1 ...), alors obtenez 12 x 10 :
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
Comme le précédent, cela produit
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
(Remarque: il n'est pas nécessaire de continuer à alterner gauche et droite sur les lignes intermédiaires, seule la position de la première et de la dernière ligne est importante. Gauche et droite peuvent être choisies arbitrairement pour toutes les autres lignes.)
Et par pure coïncidence, le quine complet fonctionne toujours:
{`"_~"{`"_~"
+{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*
}_`'"#}_`'"#
)!*}_~)!*}_~
(Je dis une coïncidence, parce que la partie qui se charge de ne pas exécuter le code interne est maintenant étrangement entrecoupée de l'autre quine, mais cela se passe toujours bien.)
Cela étant dit, j'aurais pu ajouter 44 lignes 1;
à ma soumission d'origine pour répondre à l'exigence de prime, mais 12 x 10
ça a l'air beaucoup plus net. ;)
Edit: Haha, quand j'ai dit "pure coïncidence", je n'aurais pas pu être plus précis. J'ai regardé comment fonctionne actuellement le quine final, et c'est absolument ridicule. Il y a trois blocs imbriqués (4 en fait, mais le plus interne n'est pas pertinent). La seule partie importante de l'intérieur de ces 3 blocs est qu'il contient un "
(et pas celui qu'il a fait dans la soumission d'origine, mais le même '"
qui est utilisé à la fin pour vérifier ce même caractère). La structure de base du quine est donc:
{`"_~"{`"_~"+{___'"___}_`'"#)!*}_~)!*}_~
Disséquons cela:
{`"_~" }_~ "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.";
Donc, cela fait en effet de la magie drôle, mais parce que le bloc intérieur laisse une seule chaîne sur la pile, )!*
il se trouve que cela se transforme en une chaîne vide. La seule condition est que le contenu du bloc intérieur +
ne fasse rien d'autre à la pile, alors regardons cela:
{___'"___} "Push a block which happens to contain
quotes.";
_`'"#)!* "This is from the original code and just
removes the block if it does contain
quotes.";