Quine (informatica)
In informatica, un quine è un algoritmo che riproduce il suo stesso codice sorgente senza usare funzioni di I/O (aprire il file sorgente e stampare il suo contenuto è considerato "barare").
Si tratta di un classico esercizio di programmazione che spesso viene dato a programmatori senza molta esperienza per testare le loro capacità. Per il proprio divertimento, molti programmatori esperti si impegnano a sviluppare il quine più breve possibile in ogni linguaggio di programmazione. Il nome "quine" deriva dal filosofo Willard Van Orman Quine; egli coniò infatti l'espressione paradossale "Yields falsehood when appended to its own quotation", ovvero "Produce una falsità se preceduto dalla propria citazione".
Esempi
[modifica | modifica wikitesto]C#
[modifica | modifica wikitesto]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
[modifica | modifica wikitesto]((lambda (x)
(list x (list (quote quote) x)))
(quote
(lambda (x)
(list x (list (quote quote) x)))))
Common Lisp
[modifica | modifica wikitesto]((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
OCaml
[modifica | modifica wikitesto](fun s -> Printf.printf "%s %S" s s) "(fun s -> Printf.printf \"%s %S\" s s)"
Python
[modifica | modifica wikitesto] a='a=%s;print a%%`a`';print a%`a`
Usando Python 3.0 diventa
a='a={0!r};print(a.format(a))';print(a.format(a))
Oppure
a=";print(f'a={a!r}',a)" ;print(f'a={a!r}',a)
Ed eccone un altro (è stato aggiunto un ritorno a capo per facilitare la lettura):
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)
Ruby
[modifica | modifica wikitesto]puts <<2*2,2
puts <<2*2,2
2
JavaScript
[modifica | modifica wikitesto]unescape(q="unescape(q=%22*%22).replace('*',q)").replace('*',q)
a=function (b){return "a="+b+"; alert(a(a))"}; alert(a(a))
Perl
[modifica | modifica wikitesto]$_=q{$_=q{Q};s/Q/$_/;print};s/Q/$_/;print
BASIC
[modifica | modifica wikitesto]10 C=": PRINT CHR(49)+CHR(48)+CHR(32)+CHR(67)+CHR(61)+CHR(34)+C+CHR(34)+C":
PRINT CHR(49)+CHR(48)+CHR(32)+CHR(67)+CHR(61)+CHR(34)+C+CHR(34)+C
ed eccone un altro che sfrutta i comandi READ e DATA
10 READ A$:PRINT A$+CHR$(34)+A$+CHR$(34):DATA "10 READ A$:PRINT A$+CHR$(34)+A$+CHR$(34):DATA "
Pascal
[modifica | modifica wikitesto]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.
Brainfuck
[modifica | modifica wikitesto]->+>+++>>+>++>+>+++>>+>++>>>+>+>+>++>+>>>>+++>+>>++>+>+++>>++>++>>+>>+>++>++>
+>>>>+++>+>>>>++>++>>>>+>>++>+>+++>>>++>>++++++>>+>>++>+>>>>+++>>+++++>>+>+++
>>>++>>++>>+>>++>+>+++>>>++>>+++++++++++++>>+>>++>+>+++>+>+++>>>++>>++++>>+>>
++>+>>>>+++>>+++++>>>>++>>>>+>+>++>>+++>+>>>>+++>+>>>>+++>+>>>>+++>>++>++>+>+
++>+>++>++>>>>>>++>+>+++>>>>>+++>>>++>+>+++>+>+>++>>>>>>++>>>+>>>++>+>>>>+++>
+>>>+>>++>+>++++++++++++++++++>>>>+>+>>>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>
>>+++>>++++++>>>+>++>>+++>+>+>++>+>+++>>>>>+++>>>+>+>>++>+>+++>>>++>>++++++++
>>+>>++>+>>>>+++>>++++>>+>+++>>>>>>++>+>+++>>+>++>>>>+>+>++>+>>>>+++>>+++>>>+
[[->>+<<]<+]+++++[->+++++++++<]>.[+]>>[<<+++++++[->+++++++++<]>-
.------------------->-[-<.<+>>]<[+]<+>>>]<<<[-[-[-[>>+<++++++[->+++++<]]>++++
++++++++++<]>+++<]++++++[->+++++++<]>+<<<-[->>>++<<<]>[->>.<<]<<]
HQ9+
[modifica | modifica wikitesto]Q
MS-DOS Batch
[modifica | modifica wikitesto]@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
[modifica | modifica wikitesto]<?
$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);
?>
PostScript
[modifica | modifica wikitesto](dup == {dup cvx exec} pop 8 12 getinterval =)
dup cvx exec
SQL Oracle
[modifica | modifica wikitesto]Si intende che il valore NULL valga pure come stringa vuota e che il carattere ASCII CHR(39) sia il carattere di terminazione di una stringa ('); si fa affidamento sul fatto che la colonna DUMMY della tabella DUAL restituisca la stringa 'X' e che il carattere 'X' compaia una sola volta in tutta l'espressione. Altri dialetti di SQL possono adattare questo esempio.
select replace(replace(q,t,null),z,q) from (select t,z,t||
'select replace(replace(q,t,null),z,q) from (select t,z,t||
X
||t q from (select dummy z, chr(39) t from dual))'
||t q from (select dummy z, chr(39) t from dual))
COBOL Microfocus
[modifica | modifica wikitesto]000010 IDENTIFICATION DIVISION.
000020 PROGRAM-ID. QUINE. AUTHOR. ITSELF.
000030 CONFIGURATION SECTION.
000040 SPECIAL-NAMES. SYMBOLIC CHARACTERS TT IS 35.
000050 DATA DIVISION.
000060 WORKING-STORAGE SECTION.
000070 01 IDX PIC 9(4) COMP.
000080 01 WS-SOURCE.
000090 05 WS-LINE PIC X(56) OCCURS 23 TIMES.
000100 01 WS-NUM PIC 9(6) COMP.
000110 PROCEDURE DIVISION.
000120 INITIALIZE WS-SOURCE.
000130 PERFORM DO-QUINE.
000140 PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 23
000150 DISPLAY WS-LINE(IDX)
000160 END-PERFORM.
000170 PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 23
000180 COMPUTE WS-NUM = 1000 + IDX * 10
000190 DISPLAY WS-NUM ' ' TT WS-LINE(IDX) TT
000200 END-PERFORM.
000210 DISPLAY '002000 INTO WS-SOURCE.'.
000220 DO-QUINE SECTION.
000230 STRING
001010 "000010 IDENTIFICATION DIVISION. "
001020 "000020 PROGRAM-ID. QUINE. AUTHOR. ITSELF."
001030 "000030 CONFIGURATION SECTION. "
001040 "000040 SPECIAL-NAMES. SYMBOLIC CHARACTERS TT IS 35."
001050 "000050 DATA DIVISION. "
001060 "000060 WORKING-STORAGE SECTION. "
001070 "000070 01 IDX PIC 9(4) COMP. "
001080 "000080 01 WS-SOURCE. "
001090 "000090 05 WS-LINE PIC X(56) OCCURS 23 TIMES."
001100 "000100 01 WS-NUM PIC 9(6) COMP. "
001110 "000110 PROCEDURE DIVISION. "
001120 "000120 INITIALIZE WS-SOURCE. "
001130 "000130 PERFORM DO-QUINE. "
001140 "000140 PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 23"
001150 "000150 DISPLAY WS-LINE(IDX) "
001160 "000160 END-PERFORM. "
001170 "000170 PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 23"
001180 "000180 COMPUTE WS-NUM = 1000 + IDX * 10 "
001190 "000190 DISPLAY WS-NUM ' ' TT WS-LINE(IDX) TT "
001200 "000200 END-PERFORM. "
001210 "000210 DISPLAY '002000 INTO WS-SOURCE.'. "
001220 "000220 DO-QUINE SECTION. "
001230 "000230 STRING "
002000 INTO WS-SOURCE.
RPGfree
[modifica | modifica wikitesto]dcl-f qprint printer(132); //------------------------------------------not optimized !--------* dcl-s sss char(80) dim(50) ctdata; dcl-s x3 packed(3); dcl-s wprtline char(80); //-----------------------------------------------------------------* *inlr = *on; for x3 = 1 by 1 to 21; wprtline = sss(x3); except xline; endfor; wprtline = '**'; except xline; for x3 = 1 by 1 to 21; wprtline = sss(x3); except xline; endfor; return; //-----------------------------------------------------------------* oqprint e xline 001 o wprtline ** dcl-f qprint printer(132); //------------------------------------------not optimized !--------* dcl-s sss char(80) dim(50) ctdata; dcl-s x3 packed(3); dcl-s wprtline char(80); //-----------------------------------------------------------------* *inlr = *on; for x3 = 1 by 1 to 21; wprtline = sss(x3); except xline; endfor; wprtline = '**'; except xline; for x3 = 1 by 1 to 21; wprtline = sss(x3); except xline; endfor; return; //-----------------------------------------------------------------* oqprint e cline 001 o wprtline
Bash
[modifica | modifica wikitesto]Il più piccolo quine Bash
b=\' c=\\ a='echo b=$c$b c=$c$c a=$b$a$b; echo $a'
echo b=$c$b c=$c$c a=$b$a$b; echo $a
versione da shell su una sola riga:
b=\' c=\\ a='echo -n b=$c$b c=$c$c a=$b$a$b\;; echo $a';echo -n b=$c$b c=$c$c a=$b$a$b\;; echo $a
Voci correlate
[modifica | modifica wikitesto]- Olimpiadi internazionali di codice C offuscato
- Linguaggio di programmazione
- Lista dei linguaggi di programmazione
- Self-interpreter
- Self-replication
Altri progetti
[modifica | modifica wikitesto]- Wikimedia Commons contiene immagini o altri file sul quine
Collegamenti esterni
[modifica | modifica wikitesto]- (EN) Denis Howe, quine, in Free On-line Dictionary of Computing. Disponibile con licenza GFDL
- http://www.nyx.net/~gthompso/quine.htm The Quine Page (di Gary P. Thompson)
- http://c2.com/cgi/wiki?QuinePrograms