Vai al contenuto

Quine (informatica)

Da Wikipedia, l'enciclopedia libera.
Implementazione in Java di un quine

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".

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);
     }
   }
}
((lambda (x)
            (list x (list (quote quote) x)))
        (quote
            (lambda (x)
                (list x (list (quote quote) x)))))
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
(fun s -> Printf.printf "%s %S" s s) "(fun s -> Printf.printf \"%s %S\" s s)"
 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)
puts <<2*2,2
puts <<2*2,2
2
unescape(q="unescape(q=%22*%22).replace('*',q)").replace('*',q)
 a=function (b){return "a="+b+"; alert(a(a))"}; alert(a(a))
$_=q{$_=q{Q};s/Q/$_/;print};s/Q/$_/;print
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 "
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.
->+>+++>>+>++>+>+++>>+>++>>>+>+>+>++>+>>>>+++>+>>++>+>+++>>++>++>>+>>+>++>++>
+>>>>+++>+>>>>++>++>>>>+>>++>+>+++>>>++>>++++++>>+>>++>+>>>>+++>>+++++>>+>+++
>>>++>>++>>+>>++>+>+++>>>++>>+++++++++++++>>+>>++>+>+++>+>+++>>>++>>++++>>+>>
++>+>>>>+++>>+++++>>>>++>>>>+>+>++>>+++>+>>>>+++>+>>>>+++>+>>>>+++>>++>++>+>+
++>+>++>++>>>>>>++>+>+++>>>>>+++>>>++>+>+++>+>+>++>>>>>>++>>>+>>>++>+>>>>+++>
+>>>+>>++>+>++++++++++++++++++>>>>+>+>>>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>
>>+++>>++++++>>>+>++>>+++>+>+>++>+>+++>>>>>+++>>>+>+>>++>+>+++>>>++>>++++++++
>>+>>++>+>>>>+++>>++++>>+>+++>>>>>>++>+>+++>>+>++>>>>+>+>++>+>>>>+++>>+++>>>+
[[->>+<<]<+]+++++[->+++++++++<]>.[+]>>[<<+++++++[->+++++++++<]>-
.------------------->-[-<.<+>>]<[+]<+>>>]<<<[-[-[-[>>+<++++++[->+++++<]]>++++
++++++++++<]>+++<]++++++[->+++++++<]>+<<<-[->>>++<<<]>[->>.<<]<<]
Q
@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
<?
  $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);
  ?>
(dup == {dup cvx exec} pop 8 12 getinterval =)
dup cvx exec

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.
        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

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]

Altri progetti

[modifica | modifica wikitesto]

Collegamenti esterni

[modifica | modifica wikitesto]