Jump to content

Quine (computing): Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
fixed typo
Radiation-hardened Quine
Line 304: Line 304:
|author = Rijnard van Tonder
|author = Rijnard van Tonder
}}</ref>
}}</ref>

==Radiation-hardened Quine==

A radiation-hardened Quine is a Quine that can have any single character removed and still produce the original program with no missing character. Of necessity such Quine's are much more concovuted that ordinary Quines, as is seen by the following example in [[Ruby]] <ref>{{cite web
|url = https://github.com/mame/radiation-hardened-quine
|title = Radiation-hardened Quine
|author = Yusuke Endoh
}}</ref>

<source lang="ruby">
eval='eval$q=%q(puts %q(10210/#{1 1 if 1==21}}/.i rescue##/

1 1"[13,213].max_by{|s|s.size}#"##").gsub(/\d/){["=\47eval$q=%q(#$q)#\47##\47

",:eval,:instance_,"||=9"][eval$&]}
exit)#'##'

instance_eval='eval$q=%q(puts %q(10210/#{1 1 if 1==21}}/.i rescue##/

1 1"[13,213].max_by{|s|s.size}#"##").gsub(/\d/){["=\47eval$q=%q(#$q)#\47##\47

",:eval,:instance_,"||=9"][eval$&]}
exit)#'##'

/#{eval eval if eval==instance_eval}}/.i rescue##/

eval eval"[eval||=9,instance_eval||=9].max_by{|s|s.size}#"##"
</source>


==See also==
==See also==

Revision as of 22:04, 23 February 2014

A quine's output is exactly the same as its source code.

A quine is a computer program which takes no input and produces a copy of its own source code as its only output. The standard terms for these programs in the computability theory and computer science literature are self-replicating programs, self-reproducing programs, and self-copying programs.

A quine is a fixed point of an execution environment, when the execution environment is viewed as a function. Quines are possible in any Turing complete programming language, as a direct consequence of Kleene's recursion theorem. For amusement, programmers sometimes attempt to develop the shortest possible quine in any given programming language.

The name "quine" was coined by Douglas Hofstadter, in his popular science book Gödel, Escher, Bach: An Eternal Golden Braid, in the honor of philosopher Willard Van Orman Quine (1908–2000), who made an extensive study of indirect self-reference, and in particular for the following paradox-producing expression, known as Quine's paradox:

"Yields falsehood when preceded by its quotation" yields falsehood when preceded by its quotation.

In some languages, an empty source file is a fixed point of the language, producing no output. Such an empty program, submitted as "the world's smallest self reproducing program", once won the "worst abuse of the rules" prize in the International Obfuscated C Code Contest.[1]

History

The idea of self-reproducing programs first appeared in Paul Bratley and Jean Millo's article "Computer Recreations: Self-Reproducing Automata" in 1972.[2] Bratley first became interested in self-reproducing programs after seeing the first known such program written in Atlas Autocode at Edinburgh in the 1960s by the University of Edinburgh lecturer and researcher Hamish Dewar. This program appears below:

%BEGIN
!THIS IS A SELF-REPRODUCING PROGRAM
%ROUTINESPEC R
R
PRINT SYMBOL(39)
R
PRINT SYMBOL(39)
NEWLINE
%CAPTION %END~
%CAPTION %ENDOFPROGRAM~
%ROUTINE R
%PRINTTEXT '
%BEGIN
!THIS IS A SELF-REPRODUCING PROGRAM
%ROUTINESPEC R
R
PRINT SYMBOL(39)
R
PRINT SYMBOL(39)
NEWLINE
%CAPTION %END~
%CAPTION %ENDOFPROGRAM~
%ROUTINE R
%PRINTTEXT '
%END
%ENDOFPROGRAM

Examples

The following Java code demonstrates the basic structure of a quine.

public class Quine
{
  public static void main(String[] args)
  {
    char q = 34;      // Quotation mark character
    String[] l = {    // Array of source code
    "public class Quine",
    "{",
    "  public static void main(String[] args)",
    "  {",
    "    char q = 34;      // Quotation mark character",
    "    String[] l = {    // Array of source code",
    "    ",
    "    };",
    "    for(int i = 0; i < 6; i++ )          // Print opening code",
    "        System.out.println(l[i]);",
    "    for(int i = 0; i < l.length; i++)    // Print string array",
    "        System.out.println( l[6] + q + l[i] + q + ',' );",
    "    for(int i = 7; i < l.length; i++)    // Print this code",
    "        System.out.println( l[i] );",
    "  }",
    "}",
    };
    for(int i = 0; i < 6; i++)           // Print opening code
        System.out.println(l[i]);
    for(int i = 0; i < l.length; i++)    // Print string array
        System.out.println(l[6] + q + l[i] + q + ',');
    for(int i = 7; i < l.length; i++)    // Print this code
        System.out.println(l[i]);
  }
}

The source code contains a string array of itself, which is output twice, once inside quotation marks.

The same idea is used in SQL quine:

SELECT REPLACE(REPLACE('SELECT REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$") AS Quine',CHAR(34),CHAR(39)),CHAR(36),'SELECT REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$") AS Quine') AS Quine

A very concise quine with the same basic structure can be written in Lua:

x = [["x = [" .. "[" .. x .. "]" .. "]\nprint(" .. x)]]
print("x = [" .. "[" .. x .. "]" .. "]\nprint(" .. x)

And in Python:

s = 's = %r\nprint(s%%s)'
print(s%s)

Quines can take advantage of eval. For example, this Ruby quine:

eval s="print 'eval s=';p s"

Quines, per definition, cannot receive any form of input, including reading a file, which means the following shell script is not a quine.

# Invalid quine. 
# Reading the executed file from disk is cheating
cat $0

Ouroboros programs

The quine concept can be extended to multiple levels or recursion, originating what has been called[by whom?] "ouroboros programs", or quine-relays. This should not be confused with Multiquines.

Example

This Java program outputs the source for a C++ program that outputs the original Java code.

#include <iostream>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
    char q = 34;
    string l[] = {
    "    ",
    "=============<<<<<<<< C++ Code >>>>>>>>=============",
    "#include <iostream>",
    "#include <string>",
    "using namespace std;",
    "",
    "int main(int argc, char* argv[])",
    "{",
    "    char q = 34;",
    "    string l[] = {",
    "    };",
    "    for(int i = 20; i <= 25; i++)",
    "        cout << l[i] << endl;",
    "    for(int i = 0; i <= 34; i++)",
    "        cout << l[0] + q + l[i] + q + ',' << endl;",
    "    for(int i = 26; i <= 34; i++)",
    "        cout << l[i] << endl;",
    "    return 0;",
    "}",
    "=============<<<<<<<< Java Code >>>>>>>>=============",
    "public class Quine",
    "{",
    "  public static void main( String[] args )",
    "  {",
    "    char q = 34;",
    "    String[] l = {",
    "    };",
    "    for(int i = 2; i <= 9; i++)",
    "        System.out.println( l[i] );",
    "    for(int i = 0; i < l.length; i++)",
    "        System.out.println(l[0] + q + l[i] + q + ',');",
    "    for(int i = 10; i <= 18; i++)",
    "        System.out.println(l[i]);",
    "  }",
    "}",
    };
    for(int i = 20; i <= 25; i++)
        cout << l[i] << endl;
    for(int i = 0; i <= 34; i++)
        cout << l[0] + q + l[i] + q + ',' << endl;
    for(int i = 26; i <= 34; i++)
        cout << l[i] << endl;
    return 0;
}
public class Quine
{
  public static void main(String[] args)
  {
    char q = 34;
    String[] l = {
    "    ",
    "=============<<<<<<<< C++ Code >>>>>>>>=============",
    "#include <iostream>",
    "#include <string>",
    "using namespace std;",
    "",
    "int main(int argc, char* argv[])",
    "{",
    "    char q = 34;",
    "    string l[] = {",
    "    };",
    "    for(int i = 20; i <= 25; i++)",
    "        cout << l[i] << endl;",
    "    for(int i = 0; i <= 34; i++)",
    "        cout << l[0] + q + l[i] + q + ',' << endl;",
    "    for(int i = 26; i <= 34; i++)",
    "        cout << l[i] << endl;",
    "    return 0;",
    "}",
    "=============<<<<<<<< Java Code >>>>>>>>==========",
    "public class Quine",
    "{",
    "  public static void main( String[] args )",
    "  {",
    "    char q = 34;",
    "    String[] l = {",
    "    };",
    "    for(int i = 2; i <= 9; i++)",
    "        System.out.println(l[i]);",
    "    for(int i = 0; i < l.length; i++)",
    "        System.out.println( l[0] + q + l[i] + q + ',' );",
    "    for(int i = 10; i <= 18; i++)",
    "        System.out.println( l[i] );",
    "  }",
    "}",
    };
    for(int i = 2; i <= 9; i++)
        System.out.println(l[i]);
    for(int i = 0; i < l.length; i++)
        System.out.println( l[0] + q + l[i] + q + ',' );
    for(int i = 10; i <= 18; i++)
        System.out.println(l[i]);
 
 }
}

Such programs have been produced with various cycle lengths:

Multiquines

David Madore, creator of Unlambda, describes multiquines as follows:[11]

"A multiquine is a set of r different programs (in r different languages — without this condition we could take them all equal to a single quine), each of which is able to print any of the r programs (including itself) according to the command line argument it is passed. (Note that cheating is not allowed: the command line arguments must not be too long — passing the full text of a program is considered cheating)."

A multiquine consisting of 2 languages (or biquine) would be a program which:

  • When run, is a quine in language X.
  • When supplied with a user-defined command line argument, would print a second program in language Y.
  • Given the second program in language Y, when run normally, would also be a quine in language Y.
  • Given the second program in language Y, and supplied with a user-defined command line argument, would produce the original program in language X.

A biquine could then be seen as a set of two programs, both of which are able to print either of the two, depending on the command line argument supplied.

A 5-part multiquine (or pentaquine) has been produced with Python, Perl, C, NewLISP, and F#[12]

Radiation-hardened Quine

A radiation-hardened Quine is a Quine that can have any single character removed and still produce the original program with no missing character. Of necessity such Quine's are much more concovuted that ordinary Quines, as is seen by the following example in Ruby [13]

eval='eval$q=%q(puts %q(10210/#{1 1 if 1==21}}/.i rescue##/

1 1"[13,213].max_by{|s|s.size}#"##").gsub(/\d/){["=\47eval$q=%q(#$q)#\47##\47

",:eval,:instance_,"||=9"][eval$&]}
exit)#'##'

instance_eval='eval$q=%q(puts %q(10210/#{1 1 if 1==21}}/.i rescue##/

1 1"[13,213].max_by{|s|s.size}#"##").gsub(/\d/){["=\47eval$q=%q(#$q)#\47##\47

",:eval,:instance_,"||=9"][eval$&]}
exit)#'##'

/#{eval eval if eval==instance_eval}}/.i rescue##/

eval eval"[eval||=9,instance_eval||=9].max_by{|s|s.size}#"##"

See also

References

  1. ^ IOCCC 1994 Worst Abuse of the Rules
  2. ^ Bratley, Paul; Millo, Jean (1972). "Computer Recreations: Self-Reproducing Automata". Software Practice and Experience. 2: 397–400. {{cite journal}}: Cite has empty unknown parameter: |1= (help)
  3. ^ Dan Piponi (5 February 2008). "A Third Order Quine in Three Languages".
  4. ^ Bruce Ediger. "Ask and ye shall receive: Self-replicating program that goes through three generations, Python, Bash, Perl".
  5. ^ b.m. (1 February 2011). "multiquine". Archived from the original on 2013-04-15.
  6. ^ Dan Piponi (30 January 2011). "Quine Central".
  7. ^ Ruslan Ibragimov (20 April 2013). "Quine Ruby -> Java -> C# -> Python" (in Russian).
  8. ^ Shinichiro Hamaji (10 November 2007). "Quine by shinh (C C++ Ruby Python PHP Perl)". (this one is also a polyglot)
  9. ^ Ku-ma-me (22 September 2009). "Uroboros Programming With 11 Programming Languages".
  10. ^ Yusuke Endoh. "Quine Relay - An uroboros program with 50 programming languages".
  11. ^ David Madore. "Quines (self-replicating programs)".
  12. ^ Rijnard van Tonder. "Pentaquine - 5 part multiquine".
  13. ^ Yusuke Endoh. "Radiation-hardened Quine".

Further reading