C Self-reproducing Programs |
Self reproducing program: quine.c |
---|
% cat quine.c char*f="char*f=%c%s%c,q='%c',n='%cn',b='%c%c';%cmain(){printf(f,q,f,q,q,b,b,b,n,n);}%c",q='"',n='\n',b='\\'; main(){printf(f,q,f,q,q,b,b,b,n,n);} % cc -o quine quine.c % quine char*f="char*f=%c%s%c,q='%c',n='%cn',b='%c%c';%cmain(){printf(f,q,f,q,q,b,b,b,n,n);}%c",q='"',n='\n',b='\\'; main(){printf(f,q,f,q,q,b,b,b,n,n);} % quine > quine_out.c % cc -o quine_out quine_out.c % quine_out char*f="char*f=%c%s%c,q='%c',n='%cn',b='%c%c';%cmain(){printf(f,q,f,q,q,b,b,b,n,n);}%c",q='"',n='\n',b='\\'; main(){printf(f,q,f,q,q,b,b,b,n,n);} % diff quine.c quine_out.c % |
The next table reformats the program to show its structure better. Note the way C declarations work: the first variable is declared as a char *, that is, a string, initialized by a string constant. The subsequent 3 variables are just declared as char.
quine.c: Reformatted |
---|
char * f = "char*f=%c%s%c,q='%c',n='%cn',b='%c%c';%cmain()(printf(f,q,f,q,q,b,b,b,n,n);}%c", q = '"', n = '\n', b = '\\'; main() { printf(f,q,f,q,q,b,b,b,n,n); } |
Finally, this next table really deconstructs the program. The main function just uses the string f as the format string for printf. Then there is a sequence of variables to print. Successive pieces of the format string are given in the left column below. Many of these are just characters to print, but now and then is a format code, either %c for a character, or %s for a string. The middle column shows the variable being printed, in case of a format code. The right column shows the actual sequence of characters that is printed, and this is just the program itself. Notice that there are no blanks. Also, the second format down is the only %s, to print the string f itself. I suspect that this is about as short as a self-reproducing program can be, but such programs can be arbitrarily large. So this represents a skeleton onto which you could graft a more complex program. An example of a very much more complicated self-reproducing program is given at: tic-tac-toe program.
Output of the printf using the format string f | ||
---|---|---|
Portion of format String | Var | Output characters |
char*f= | char*f= | |
%c | q | " |
%s | f | char*f=%c%s%c,q='%c',n='%cn',b='%c%c';%cmain()(printf(f,q,f,q,q,b,b,b,n,n);}%c |
%c | q | " |
,q=' | ,q=' | |
%c | q | " |
',n=' | ',n=' | |
%c | b | \ |
n',b=' | n',b=' | |
%c | b | \ |
%c | b | \ |
'; | '; | |
%c | n | [newline] |
main()(printf(f,q,f,q,q,b,b,b,n,n);} | main()(printf(f,q,f,q,q,b,b,b,n,n);} | |
%c | n | [newline] |
Shorter self reproducing program: quine2.c |
---|
% cat quine2.c char *p="char *p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);} % cc -o quine2 quine2.c % quine2 char *p="char *p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);} |
This program isn't quite a proper quine, but is cheating somehow. What's wrong with it?