Et Quine-program eller Quine er et program, der udsender sin egen kildekode, når det udføres. En Quine må ikke "træde uden for sig selv" ved for eksempel at udskrive indholdet af filen, der indeholder den eller bruge introspektive evner til at udskrive sin egen repræsentation. I stedet skal den beregne sin egen kildekode.
Den klassiske måde at skabe et sådant program på foregår i to trin:
- Initialiser en strengvariabel med en pladsholder til interpolation.
- Udskriv strengen og interpoler den ind i sig selv .
Tricket er at få strengen helt rigtig. Hvordan man gør dette varierer fra sprog til sprog og afhænger af, hvordan variablen er deklareret, behovet for semikolon og linjeskift, de krævede anførselstegn osv. Brugen af anførselstegn er interessant; Man skal finde en måde at angive, at et anførselstegn skal udskrives uden egentlig at bruge et anførselstegn.
Bash
Som de fleste ting i Bash, bruger dette program en interessant særhed. Selvom enkelte citater er stærke citater og ikke udvider noget, fortolket printf
oktale escape-tegn som tegn med det angivne kodepunkt:
s='s=%s;printf "$s" "$s"';printf "$s" "$s"
Python
I Python returnerer formatspecifikationen %r
automatisk enkelte citater. Det er nemmest, hvis koden slutter med et linjeskifttegn:
s='s=%r;print(s%%s)';print(s%s)
Hvis du vil have koden uden linjeskift, skal du skrive følgende:
s='s=%r;print(s%%s,sep="")';print(s%s,sep="")
JavaScript
Følgende JavaScript-quines kører under node.js. du bruger console.log
, som altid tilføjer en ny linje, så en ny linje er nødvendig i slutningen af hvert script:
s="s=%j;console.log(s,s)";console.log(s,s)
Følgende program er også interessant: det udskriver ikke hele sin repræsentation, men det er afhængigt af, at funktioner har en bestemt repræsentation:
(function a(){console.log('('+a+')()')})()
Det næste eksempel er tæt på snyd, fordi det eval
brugt:
code='var q=unescape("%27");console.log("code="+q+code+q+";eval(code)")';eval(code)
Rust
Rust giver en måde at omslutte et argument i anførselstegn i dens formaterede udskriftsmakro. Denne makro kræver dog, at det første argument i printmakroen er en streng-literal! Det er derfor bedst at bruge positional argument identifikator:
fn main(){print!("fn main(){{print!({0:?},{0:?})}}","fn main(){{print!({0:?},{0:?})}}")}
PHP
Dette PHP-program fungerer ved at gemme kildekoden i en streng og derefter bruge denne streng printf
udgange. De 39
står for ASCII-tegnet '
, for at håndtere anførselstegnene i strengen korrekt:
<?php
$code = '<?php
$code = %c%s%c;
printf($code, 39, $code, 39);
';
printf($code, 39, $code, 39);
HQ9+
Sidst men ikke mindst er HQ9+, udviklet af Cliff Biffle:
Q