Un programa quine, o quine, es un programa que imprime su propio código fuente cuando se ejecuta. Un quine no debe "salirse de sí mismo", por ejemplo imprimiendo el contenido del fichero en el que se encuentra o utilizando capacidades introspectivas para imprimir su propia representación, sino que debe calcular su propio código fuente.
La forma clásica de crear un programa de este tipo es en dos pasos:
- Inicializa una variable de cadena con un marcador de posición para la interpolación.
- Imprime la cadena y la interpola en sí misma.
La forma de hacerlo varía de un idioma a otro y depende de la declaración de las variables, la necesidad de punto y coma y saltos de línea, las comillas necesarias, etc. El tratamiento de las comillas es interesante; hay que encontrar una forma de indicar que se debe imprimir una comilla sin utilizar realmente una comilla.
Bash
Como la mayoría de las cosas en Bash, este programa utiliza una peculiaridad interesante. Aunque las comillas simples son comillas fuertes y no expanden nada, el comando printf
caracteres de escape octales como caracteres con el punto de código especificado:
s='s=%s;printf "$s" "$s"';printf "$s" "$s"
Python
En Python, el identificador de formato %r
La forma más sencilla de hacerlo es terminar el código con un carácter de nueva línea:
s='s=%r;print(s%%s)';print(s%s)
Si desea el código sin salto de línea, debe escribir lo siguiente:
s='s=%r;print(s%%s,sep="")';print(s%s,sep="")
JavaScript
Los siguientes quines de JavaScript se ejecutan bajo node.js. Utilizan console.log
, que siempre añade una nueva línea, de modo que se requiere una nueva línea al final de cada script:
s="s=%j;console.log(s,s)";console.log(s,s)
El siguiente programa también es interesante: no imprime toda su representación, pero se basa en el hecho de que las funciones tienen una representación específica:
(function a(){console.log('('+a+')()')})()
El siguiente ejemplo se acerca a la trampa, ya que eval
usado:
code='var q=unescape("%27");console.log("code="+q+code+q+";eval(code)")';eval(code)
Óxido
Rust proporciona una forma de citar un argumento en su macro de impresión formateada, pero esta macro requiere que el primer argumento de la macro de impresión sea un literal de cadena, por lo que es mejor utilizar el identificador de argumento posicional:
fn main(){print!("fn main(){{print!({0:?},{0:?})}}","fn main(){{print!({0:?},{0:?})}}")}
PHP
Este programa PHP funciona guardando el código fuente en una cadena de caracteres y luego utilizando printf
En 39
representa el carácter ASCII '
, para tratar correctamente las comillas de la cadena:
<?php
$code = '<?php
$code = %c%s%c;
printf($code, 39, $code, 39);
';
printf($code, 39, $code, 39);
HQ9+
Por último, pero no por ello menos importante, está HQ9+, desarrollado por Cliff Biffle:
Q