- Quine (programa)
-
Quine (programa)
En informática, un quine (pronunciado "kwain") es un programa (un tipo de metaprograma) 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.
Nota: simplemente abriendo el archivo fuente del programa e imprimiendo el contenido se considera hacer trampa.
Los quines se llaman así por 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".
Contenido
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 cortes 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 carácteres ú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
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.
->+>+++>>+>++>+>+++>>+>++>>>+>+>+>++>+>>>>+++>+>>++>+>+++>>++>++>>+>>+>++>++> +>>>>+++>+>>>>++>++>>>>+>>++>+>+++>>>++>>++++++>>+>>++>+>>>>+++>>+++++>>+>+++ >>>++>>++>>+>>++>+>+++>>>++>>+++++++++++++>>+>>++>+>+++>+>+++>>>++>>++++>>+>> ++>+>>>>+++>>+++++>>>>++>>>>+>+>++>>+++>+>>>>+++>+>>>>+++>+>>>>+++>>++>++>+>+ ++>+>++>++>>>>>>++>+>+++>>>>>+++>>>++>+>+++>+>+>++>>>>>>++>>>+>>>++>+>>>>+++> +>>>+>>++>+>++++++++++++++++++>>>>+>+>>>+>>++>+>+++>>>++>>++++++++>>+>>++>+>> >>+++>>++++++>>>+>++>>+++>+>+>++>+>+++>>>>>+++>>>+>+>>++>+>+++>>>++>>++++++++ >>+>>++>+>>>>+++>>++++>>+>+++>>>>>>++>+>+++>>+>++>>>>+>+>++>+>>>>+++>>+++>>>+ [[->>+<<]]<+]+++++[->+++++++++<]>.[+]>>[<<+++++++[->+++++++++<]>- .------------------->-[-<.<+>>]<[+]<+>>>]<<<[-[-[-[>>+<++++++[->+++++<]]>++++ ++++++++++<]>+++<]++++++[->+++++++<]>+<<<-[->>>++<<<]>[->>.<<]<<]
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
Categoría: Programación
Wikimedia foundation. 2010.