Un programme Quine ou Quine est un programme qui, lorsqu'il est exécuté, affiche son propre code source. Un Quine ne doit pas "sortir de lui-même", par exemple en imprimant le contenu du fichier qui le contient ou en utilisant des capacités introspectives pour imprimer sa propre représentation. Au lieu de cela, il doit calculer son propre code source.
Le processus classique de création d'un tel programme se déroule en deux étapes:
- Initialiser une variable de chaîne de caractères avec un caractère de remplacement pour l'interpolation.
- Imprimer la chaîne de caractères et l'interpoler en elle-même.
L'astuce consiste à choisir exactement la bonne chaîne de caractères. La manière de procéder varie d'une langue à l'autre et dépend de la déclaration des variables, du besoin de points-virgules et de retours à la ligne, des guillemets nécessaires, etc. La gestion des guillemets est intéressante ; il faut trouver un moyen d'indiquer qu'un guillemet doit être imprimé sans utiliser réellement un guillemet.
Bash
Comme la plupart des choses en Bash, ce programme utilise une particularité intéressante. Bien que les guillemets simples soient des guillemets forts et n'étendent rien, le programme interprète printf
caractères d'échappement octaux comme caractères avec le point de code spécifié:
s='s=%s;printf "$s" "$s"';printf "$s" "$s"
Python
En Python, l'identificateur de format retourne %r
Le plus simple est de terminer le code par un retour à la ligne.:
s='s=%r;print(s%%s)';print(s%s)
Si l'on souhaite obtenir le code sans retour à la ligne, il faut écrire ce qui suit:
s='s=%r;print(s%%s,sep="")';print(s%s,sep="")
JavaScript
Les quines JavaScript suivantes fonctionnent sous node.js. Elles utilisent console.log
, qui ajoute toujours une nouvelle ligne, de sorte qu'une nouvelle ligne est nécessaire à la fin de chaque script:
s="s=%j;console.log(s,s)";console.log(s,s)
Le programme suivant est également intéressant : il n'imprime pas toute sa représentation, mais il s'appuie sur le fait que les fonctions ont une représentation spécifique:
(function a(){console.log('('+a+')()')})()
L'exemple suivant est proche de la triche, puisqu'il s'agit de eval
utilise:
code='var q=unescape("%27");console.log("code="+q+code+q+";eval(code)")';eval(code)
Rust
Rust offre la possibilité de mettre un argument entre guillemets dans sa macro d'impression formatée. Cette macro exige cependant que le premier argument de la macro d'impression soit un littéral de chaîne de caractères ! Il est donc préférable d'utiliser l'identificateur d'argument de position:
fn main(){print!("fn main(){{print!({0:?},{0:?})}}","fn main(){{print!({0:?},{0:?})}}")}
PHP
Ce programme PHP fonctionne en sauvegardant le code source dans une chaîne de caractères, puis en utilisant printf
La 39
représente le caractère ASCII '
, pour traiter correctement les guillemets dans la chaîne de caractères:
<?php
$code = '<?php
$code = %c%s%c;
printf($code, 39, $code, 39);
';
printf($code, 39, $code, 39);
HQ9+
Enfin, HQ9+, développé par Cliff Biffle, est le dernier à être présenté.:
Q