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 deze in zichzelf .
De truc is om de snaar precies goed te krijgen. Hoe je dit moet doen, verschilt van taal tot taal en hangt af van hoe de variabele wordt gedeclareerd, de behoefte aan puntkomma's en nieuwe regels, de vereiste aanhalingstekens, enz. Het gebruik van aanhalingstekens is interessant; je moet een manier vinden om te specificeren 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=\47%s\47;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-codes draaien op Node.js. jij gebruikt console.log, die altijd een nieuwe regel toevoegt, dus aan het einde van elk script is een nieuwe regel nodig:
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