Een quine programma, of quine, is een programma dat zijn eigen broncode afdrukt wanneer het wordt uitgevoerd. Een quine mag niet "buiten zichzelf treden", bijvoorbeeld door de inhoud van het bestand waarin het staat af te drukken of door introspectieve mogelijkheden te gebruiken om zijn eigen representatie af te drukken. In plaats daarvan moet het zijn eigen broncode berekenen.
De klassieke manier om zo'n programma te maken is in twee stappen:
- Initialiseer een tekenreeksvariabele met een plaatshouder voor de interpolatie.
- Druk de string af en interpoleer hem in zichzelf.
De truc is om de string precies goed te krijgen. Hoe je dit doet verschilt van taal tot taal en hangt af van de declaratie van de variabelen, de noodzaak voor puntkomma's en regeleinden, de vereiste aanhalingstekens, etc. Omgaan met aanhalingstekens is interessant; je moet een manier vinden om aan te geven dat een aanhalingsteken moet worden afgedrukt zonder daadwerkelijk een aanhalingsteken te gebruiken.
Bash
Zoals de meeste dingen in Bash, gebruikt dit programma een interessante eigenaardigheid. Hoewel enkele aanhalingstekens sterke aanhalingstekens zijn en niets vergroten, gebruikt de printf
octale escape-tekens als tekens met het opgegeven codepunt:
s='s=%s;printf "$s" "$s"';printf "$s" "$s"
Python
In Python is de formaat-identifier %r
De eenvoudigste manier om dit te doen is door de code te eindigen met een newline-teken:
s='s=%r;print(s%%s)';print(s%s)
Als je de code zonder regeleinden wilt, moet je het volgende schrijven:
s='s=%r;print(s%%s,sep="")';print(s%s,sep="")
JavaScript
De volgende JavaScript-quines draaien onder node.js. Ze gebruiken console.log
, die altijd een nieuwe regel toevoegt, zodat aan het einde van elk script een nieuwe regel nodig is:
s="s=%j;console.log(s,s)";console.log(s,s)
Het volgende programma is ook interessant: het drukt niet de volledige representatie af, maar vertrouwt op het feit dat functies een specifieke representatie hebben:
(function a(){console.log('('+a+')()')})()
Het volgende voorbeeld is bijna valsspelen, omdat het eval
tweedehands:
code='var q=unescape("%27");console.log("code="+q+code+q+";eval(code)")';eval(code)
Roest
Rust biedt een manier om een argument te citeren in zijn geformatteerde afdrukmacro, maar deze macro vereist dat het eerste argument van de afdrukmacro een letterlijke string is! Het is daarom het beste om de positionele argumentidentifier te gebruiken:
fn main(){print!("fn main(){{print!({0:?},{0:?})}}","fn main(){{print!({0:?},{0:?})}}")}
Php
Dit PHP-programma werkt door de broncode op te slaan in een tekenreeks en dan het volgende te gebruiken printf
De 39
staat voor het ASCII-teken '
, om de aanhalingstekens in de string correct te verwerken:
<?php
$code = '<?php
$code = %c%s%c;
printf($code, 39, $code, 39);
';
printf($code, 39, $code, 39);
HQ9+
Last but not least is er HQ9+, dat is ontwikkeld door Cliff Biffle:
Q