Cela a été inspiré par Print a Negative of your Code et Golf a quine mutual .
Considérez un rectangle de caractères répondant aux restrictions suivantes:
- Se compose uniquement de caractères ASCII imprimables
- Dimensions supérieures à 1
- Chaque ligne et chaque colonne contient au moins un espace.
- Chaque ligne et chaque colonne contient au moins un caractère non espace.
Par exemple, ce qui suit est un rectangle 6x4 valide:
%n 2e
1 g 3
&* __
3
Un négatif pour ce rectangle est défini comme un rectangle de dimensions égales, avec tous les espaces remplacés par des caractères non-espace et tous les caractères non-espace remplacés par des espaces. Un négatif du rectangle ci-dessus pourrait être:
f ^
33 >
9 $
^ }|Q'
Tout caractère ASCII imprimable non-espace peut être utilisé pour remplacer un espace.
Tâche
Votre tâche consiste à écrire un programme avec un code source rectangulaire, qui génère un négatif valide pour lui-même. Le négatif émis doit également être un programme valide, dans la même langue que l'original, et il doit sortir la source de l'original.
Aucun espace de fin ne peut être ajouté ou supprimé, à l'exception d'une seule nouvelle ligne de fin à la fin de chaque sortie, qui est facultative.
Aucun programme n'est autorisé à lire le code source de l'un ou l'autre; les environnements REPL ne peuvent pas non plus être supposés.
Notation
Votre score est le produit des dimensions de votre code (c'est-à-dire si votre code source est dans un rectangle de 12 x 25, votre score est de 12 * 15 = 180). De plus, pour chaque caractère utilisé dans un commentaire, votre score augmente de 2 (si vous utilisez /* .. */
une fois dans votre code et que votre code est dans un rectangle de 10 x 10, votre score serait de 10 * 10 + 8 * 2 = 116).
Le score le plus bas l'emporte.
S'il y a égalité, la soumission avec le moins d'espaces dans le programme (l'original ou le négatif, selon le moins d'espaces) gagne.
S'il y a encore égalité, la réponse précédente l'emportera.
Il y a un bonus de -52% si la combinaison de l'original et du négatif produit une quine normale. Par exemple:
Original Negative Combined
A A B B BABA
A A B B ABAB
Réponses:
CJam, (
51 49 47 46 4542 x 2) * 48% = 40,32L'exécution du code ci-dessus donne cette sortie:
en cours d'exécution, imprime la source d'origine.
La source et la sortie sont simplement des lignes permutées.
Maintenant vient la magie.
Superposition de la source et des résultats de sortie dans le code suivant:
ce qui est une quine parfaite!
Essayez-les en ligne ici
Comment ça marche
Toute la logique d'impression est dans la première ligne elle-même qui gère les trois cas expliqués plus loin.
Le tableau dans la dernière ligne ci-dessus est le tableau qui a des blocs de code correspondant aux trois cas.
Cas 1
Dans ce cas, la longueur de la pile restante était de 0 car lorsque le bloc a été exécuté, il ne disposait que de la copie du bloc lui-même, qui a été initialement extraite à la troisième étape ci-dessus. Nous retirons donc l'index
0
du dernier tableau et l'exécutons:Dans ce cas, la deuxième ligne est un no-op en ce qui concerne l'impression de la sortie.
Cas 2
Dans ce cas, la pile contenait déjà une chaîne vide, donc lorsque le bloc de code copié a été exécuté, elle avait 2 éléments - une chaîne vide et le bloc de code lui-même. Nous retirons donc l'index
1
du dernier tableau et l'exécutons:Cas 3
Dans ce cas, la pile comporte 6 éléments. Ainsi, après avoir sauté le dernier bloc de code, la longueur restante du tableau est 5. Nous prenons l'index
5
du tableau et l'exécutons. (Notez que dans un tableau d'3
éléments, index5
est index5%3 = 2
)la source
Python, 97x2 + 2 = 196
Pas une bonne solution pour commencer, mais au moins ça marche (je pense).
Sortie:
la source
CJam, (
5856544846 x 2) * 48% = 44,16qui imprime
Les caractères non-espace dans chaque ligne restent les mêmes entre les deux quines mutuelles.
Mais maintenant, la partie vraiment douce:
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 donne0
sinon il donne1
. 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:
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 :
Comme le précédent, cela produit
(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:
(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, mais12 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:
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:la source
Y/2
dans le quine combiné?CJam,
423733 x 2 = 66qui imprime
(Les lignes sont inversées et un
1
se transforme en a0
.)Testez-le ici.
Comment ça marche
Tout d'abord, vous devez comprendre le quine de base CJam:
Les accolades définissent simplement un bloc de code, comme une fonction, qui n'est pas immédiatement exécuté. Si un bloc non exécuté reste sur la pile, son code source (y compris les accolades) est imprimé.
_
duplique le bloc et~
exécute la deuxième copie. Le bloc lui-même pousse simplement la chaîne contenant_~
. Donc, ce code laisse la pile dans l'état suivant:Le bloc et la chaîne sont simplement imprimés dos à dos à la fin du programme, ce qui en fait une quine.
La beauté de ceci est que nous pouvons faire tout ce que nous voulons dans le bloc, et cela reste une quine, car chaque morceau de code sera automatiquement imprimé dans le contenu du bloc. Nous pouvons également modifier le bloc, en obtenant sa représentation de chaîne avec
`
(qui est juste une chaîne du bloc avec des accolades).Voyons maintenant cette solution. Notez que l'une ou l'autre partie du quine mutuel contient du bloc de type quine avec
_~
, et anL
. LeL
pousse une chaîne vide sur la pile, ce qui ne contribue pas à la sortie. Voici donc ce que fait le bloc:Donc, cela fera la partie quine, mais échangez un 1 pour un 0, et cela ajoutera également une autre ligne à un
L
, où le code ci-dessus a un espace. Le hic, c'est que l'ordre de ces deux lignes est déterminé par l'échange à l'intérieur{ }*
. Et parce que la partie extérieure du quine mutuel a le0
devant remplacé par un1
, il n'exécute jamais cet échange, et produit donc à nouveau l'ordre d'origine.la source
CJam, 27 × 2 = 54
Sortie:
'A'B>
compare les caractères A et B.' '\n >
renvoie 1 car 32> 10 et' \n' >
renvoie 0 car les deux espaces sont égaux.la source
CJam,
3029 x 2 = 58Les sorties:
qui sort la source d'origine.
Ceci est basé sur le même principe que mon autre solution.
Essayez-le en ligne ici
la source