Quine (programa)

En programación, un quine (pronunciado "kwain") es un programa (un tipo de Metaprogramación) que produce su código fuente como su salida única. Para diversión, algunos hackers intentan desarrollar el quine más corto posible en cualquier lenguaje de programación. Simplemente abriendo el archivo fuente del programa e imprimiendo el contenido se considera hacer trampa.

El término quine fue acuñado por Douglas Hofstadter, en su obra Gödel, Escher, Bach: un Eterno y Grácil Bucle, en honor a Willard Van Orman Quine, que hizo un estudio extensivo de autoreferencia indirecta y sugirió un caso famoso de paradoja sin autoreferencia directa: "Da como resultado un enunciado falso si es precedido por su cita" da como resultado un enunciado falso si es precedido por su cita.

Ejemplos

C
#include<stdio.h>
char*i="\\#include<stdio.h>",n='\n',q='"',*p=
"%s%cchar*i=%c%c%s%c,n='%cn',q='%c',*p=%c%c%s%c,*m=%c%c%s%c%c;%s%c",*m=
"int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);}"
;int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);}

Otro (este debe ser una sola línea, y supone que el compilador ejecuta en una máquina que usa el código ASCII):
extern printf(char*,...);main(){char*a="extern printf(char*,...);
main(){char*a=%c%s%c;printf(a,34,a,34,10);}%c";printf(a,34,a,34,10);}

O aún más corto (aunque no es código C99 de ISO correcto):
main(){char*a="main(){char*a=%c%s%c;printf(a,34,a,34);}";printf(a,34,a,34);}

C#
Nota: Debe ser una sola línea. Los saltos de línea se agregaron para hacerlo más fácil de leer.
 using System;
 namespace quine
 {
   class Program
   {
     [STAThread]
     static void Main(string[] args)
     {
       string s = "using System;{0}namespace quine{0}{2}{0}{1}class Program{0}
 {1}{2}{0}{1}{1}[STAThread]{0}{1}{1}static void Main(string[] args){0}{1}{1}{2}{0}{1}{1}{1}
 string s = {4}{6}{4};{0}{1}{1}{1}Console.Write(s, Environment.NewLine, {4}{5}t{4}, {4}{2}
 {4}, {4}{3}{4}, {4}{5}{4}{4}, {4}{5}{5}{4}, s);{0}{1}{1}{3}{0}{1}{3}{0}{3}";
       Console.Write(s, Environment.NewLine, "\t", "{", "}", "\"", "\\", s);
     }
   }
 }

Scheme
    ((lambda (x)
            (list x (list (quote quote) x)))
        (quote
            (lambda (x)
                (list x (list (quote quote) x)))))

Common Lisp

    (funcall (lambda (x) 
               (append x (list (list 'quote x)))))
             '(funcall (lambda (x) 
                          (append x (list (list 'quote x))))))

Ocaml

 (fun s -> Printf.printf "%s %S" s s) "(fun s -> Printf.printf \"%s %S\" s s)"

Python
 a='a=%s;print a%%`a`';print a%`a`

Otro:
 b='\\';g='"';p='%';s="b='%s%s';g='%s';p='%s';s=%s%s%s;print s%s(b,b,g,p,g,s,g,p)";print s%(b,b,g,p,g,s,g,p)
Y otro que comparte los caracteres últimos con la anterior (solamente para mostrar que asignaciones múltiples no salva mecanografía):
 b,g,p,s='\\','"','%',"b,g,p,s='%s%s','%s','%s',%s%s%s;print s%s(b,b,g,p,g,s,g,p)";print s%(b,b,g,p,g,s,g,p)

JavaScript

 unescape(q="unescape(q=%22*%22).replace('*',q)").replace('*',q)

Perl
$_=q{$_=q{Q};s/Q/$_/;print};s/Q/$_/;print

El más corto conocido:
open+0;print<0>

Y una combinación de Perl y script de shell:
perl -le '$n=q{perl -le a$n=q{$x};($_=$n)=~s/\141/\47/g;s/\$x/$n/;printa};($_=$n)=~s/\141/\47/g;s/\$x/$n/;print'

BASIC

 10 LIST

Pascal

 const a='const a=';b='begin write(a,#39,a,#39#59#98#61#39,b,#39#59#10,b) end.';
 begin write(a,#39,a,#39#59#98#61#39,b,#39#59#10,b) end.

Comentario 1: En el caso de una implementación DOS de Pascal, la salida de la pantalla puede parecer bastante desorientadora. En ese caso, sería apropiado sustituir ambas instancias de "#10" con "#13#10" e insertar un CR antes del LF al fin de la primera línea.

Comentario 2: El programa se puede hace todavía más corto porque ambas instancias de ") end." se pueden sustituir con ")end." (aunque le hace difícil de leer). Se puede acortar más por borrar ambas instancias de "#10" y escribiendo el programa en una sola línea en vez de dos líneas. Después de los cambios, el programa parecerá como sigue:

 const a='const a=';b='begin write(a,#39,a,#39#59#98#61#39,b,#39#59,b)end.';begin write(a,#39,a,#39#59#98#61#39,b,#39#59,b)end.

Otro (Borland Pascal and Free Pascal):

 const a='const a=;begin write(copy(a,1,8),#39,a,#39,copy(a,9,99)) end.';begin write(copy(a,1,8),#39,a,#39,copy(a,9,99)) end.

Otro (Borland Pascal and Free Pascal):

 const a:string='const a:string=;begin insert(#39+a+#39,a,16);write(a) end.';begin insert(#39+a+#39,a,16);write(a) end.

Brainfuck
Nota: Debe ser una sola línea. Los cortes de línea se agregaron para hacerlo más fácil de leer.

<nowiki>
 ->+>+++>>+>++>+>+++>>+>++>>>+>+>+>++>+>>>>+++>+>>++>+>+++>>++>++>>+>>+>++>++>
 +>>>>+++>+>>>>++>++>>>>+>>++>+>+++>>>++>>++++++>>+>>++>+>>>>+++>>+++++>>+>+++
 >>>++>>++>>+>>++>+>+++>>>++>>+++++++++++++>>+>>++>+>+++>+>+++>>>++>>++++>>+>>
 ++>+>>>>+++>>+++++>>>>++>>>>+>+>++>>+++>+>>>>+++>+>>>>+++>+>>>>+++>>++>++>+>+
 ++>+>++>++>>>>>>++>+>+++>>>>>+++>>>++>+>+++>+>+>++>>>>>>++>>>+>>>++>+>>>>+++>
 +>>>+>>++>+>++++++++++++++++++>>>>+>+>>>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>
 >>+++>>++++++>>>+>++>>+++>+>+>++>+>+++>>>>>+++>>>+>+>>++>+>+++>>>++>>++++++++
 >>+>>++>+>>>>+++>>++++>>+>+++>>>>>>++>+>+++>>+>++>>>>+>+>++>+>>>>+++>>+++>>>+
 [[->>+<<]]<+]+++++[->+++++++++<]>.[+]>>[<<+++++++[->+++++++++<]>-
 .------------------->-[-<.<+>>]<[+]<+>>>]<<<[-[-[-[>>+<++++++[->+++++<]]>++++
 ++++++++++<]>+++<]++++++[->+++++++<]>+<<<-[->>>++<<<]>[->>.<<]<<]
</nowiki>

HQ9+

 Q

DOS Batch

  @echo off
  %1 %2
  call %0 goto e %%
  call %0 goto e %%3 echo.%%4
  echo :f
  goto f
  :e
  echo.%4@echo off
  echo.%4%31 %32
  echo.%4call %30 goto e %3%3
  echo.%4call %30 goto e %3%33 echo.%3%34
  echo.%4echo :f
  echo.%4goto f
  echo.%4:e
  :f

PHP
<?
$a='chr(60).chr(63).chr(10).chr(36).chr(97).chr(61).chr(39).$a.chr(39).chr(59).chr(10)."echo $a;".chr(10).chr(63).chr(62)';
echo chr(60).chr(63).chr(10).chr(36).chr(97).chr(61).chr(39).$a.chr(39).chr(59).chr(10)."echo $a;".chr(10).chr(63).chr(62);
?>
  
<?
$a='<?
$a=2;
echo str_replace(1+1,chr(39).$a.chr(39),$a);
?>';
echo str_replace(1+1,chr(39).$a.chr(39),$a);
?>

PL/I
Nota: Este es el quine de PL/I más pequeño posible que compila usando el compilador OS PL/I V2.3.0, pero requiere un margen izquierdo de 1 y la opción COMPILE para parar una cantidad significativo de errores):

   %dcl z%z='put edit';proc options(main;q=''''put list(m;do i=1,2;z(q)skip;do j=
  1to 78c=substr(m(i),j;if c=q z(c;z(c;end;z(q',';dcl(c,q)char,m(2)char(99)init(
  '%dcl z%z=''put edit'';proc options(main;q=''''''''put list(m;do i=1,2;z(q)skip;do j=',
  '1to 78c=substr(m(i),j;if c=q z(c;z(c;end;z(q'','';dcl(c,q)char,m(2)char(99)init(',

PostScript

  (dup == {dup cvx exec} pop 8 12 getinterval =)
  dup cvx exec

Visual FoxPro

  CLEAR
  SET TALK OFF
  SET TEXTMERGE ON
  \CLEAR
  \SET TALK OFF
  \SET TEXTMERGE ON

Enlaces externos

 La página de los quines (por Gary P. Thompson)
 Los programas quine al wiki del Portland Pattern Repository
 Una página sobre los quines 
 Unos participantes en un concurso de hacer quines en JavaScript 
 Un quine HTML con uso de CSS apegado a la norma, incluyendo resaltado de la sintaxis
 "Palíndromo quine": una página web que es lo mismo que su código fuente, lo mismo de izquierda a derecha que de derecha a izquierda, los mismo de arriba para abajo que de abajo para arriba.

Programación
Willard Van Orman Quine