Iterating quines Several people have had the idea of creating a sequence, p[0]...p[n], of programs, such that the output of p[i] is the source for p[i+1] 0 <= i < n, and the output of p[n] is the source for p[0]. Author: Joseph deu Ngoc /* Self-printing program by Joseph Deu Ngoc */ /* Program Number: 0 */ #define MAXPROGRAMS 4 void main() { char a='"'; char b='\\'; char c='\n'; char *d="/* Self-printing program by Joseph Deu Ngoc */%c/* Program Number: %d */%c#define MAXPROGRAMS %d%c%cvoid main() {%c char a='%c';%c char b='%c%c';%c char c='%cn';%c char *d=%c%s%c;%c int e=%d;%c e=(e+1)%%MAXPROGRAMS;%c printf(d,c,e,c,MAXPROGRAMS,c,c,c,a,c,b,b,c,b,c,a,d,a,c,e,c,c,c,c);%c}%c"; int e=0; e=(e+1)%MAXPROGRAMS; printf(d,c,e,c,MAXPROGRAMS,c,c,c,a,c,b,b,c,b,c,a,d,a,c,e,c,c,c,c); } Author: Wang TianXing (gztxwang@public1.guangzhou.gd.cn) Note:C-Pascal Pair the C main(){char*p="program p;begin writeln(%cmain(){char*p=%c%s%c; printf(p,39,34,p,34,39);}%c)end.";printf(p,39,34,p,34,39);} the pascal program p;begin writeln('main(){char*p="program p;begin writeln(%cmain(){char*p= %c%s%c; printf(p,39,34,p,34,39);}%c)end."; printf(p,39,34,p,34,39);}')end. Author: Frank Stajano Note: Python. This is the female ("x") program... from string import replace def r(s):return replace(replace(replace(s,"x","$"),"y","x"),"$","y") z='from string import replace\012def r(s):return replace(replace(replace(s,"x", "$"),"y","x"),"$","y")\012z=%s;';x='y=%s;print z%%`z`+y%%`r(y)`';print z%`z`+x% `r(x)` ...which generates the male ("y") program below, and vice versa: from string import replace def r(s):return replace(replace(replace(s,"x","$"),"y","x"),"$","y") z='from string import replace\012def r(s):return replace(replace(replace(s,"x", "$"),"y","x"),"$","y")\012z=%s;';y='x=%s;print z%%`z`+x%%`r(x)`';print z%`z`+y% `r(y)` Author: Frank Stajano Note: Tcl. Here is the male (y)... set z {proc r {s} {regsub -all x $s = a;regsub -all y $a x b;regsub -all = $b y c;return $c}};set y {set z {%s};set x {%s};eval $z;puts [format $x $z [r $x]]} ;eval $z;puts [format $y $z [r $y]] ...and the female (x) set z {proc r {s} {regsub -all x $s = a;regsub -all y $a x b;regsub -all = $b y c;return $c}};set x {set z {%s};set y {%s};eval $z;puts [format $y $z [r $y]]} ;eval $z;puts [format $x $z [r $x]] Author: Frank Stajano Note: Tcl-Python pair this is the Tcl writing the Python: set pythonu {sqs=" ' ";sQs=" [format %c 39] ";sds=' " ';sDs=" [format %c 34] "; d='"';q="'";} set pythonn {import string r=string.replace tclnu='''set pythonu {U} set pythonn {N}''';print tclnu} set pythonb {tclb='set pythonb {B}; puts $pythonu; regsub -all [format %c 39] $ pythonn [format %c 34] ndouble; regsub U $ndouble $pythonu nn; regsub N $nn $py thonn n; puts $n; regsub -all [format %c 39] $pythonb [format %c 34] bb; regsub B $pythonb $bb b; puts $b';print r(r(r(tclb,sqs,sQs),sds,sDs),d,q)}; puts $pyt honu; regsub -all [format %c 39] $pythonn [format %c 34] ndouble; regsub U $ndo uble $pythonu nn; regsub N $nn $pythonn n; puts $n; regsub -all [format %c 39] $pythonb [format %c 34] bb; regsub B $pythonb $bb b; puts $b and this is the Python writing the Tcl: sqs=" ' ";sQs=" [format %c 39] ";sds=' " ';sDs=" [format %c 34] ";d='"';q="'"; import string r=string.replace tclnu="""set pythonu {sqs=" ' ";sQs=" [format %c 39] ";sds=' " ';sDs=" [format %c 34] ";d='"';q="'";} set pythonn {import string r=string.replace tclnu='''set pythonu {U} set pythonn {N}''';print tclnu}""";print tclnu tclb='set pythonb {tclb="set pythonb {B}; puts $pythonu; regsub -all [format %c 39] $pythonn [format %c 34] ndouble; regsub U $ndouble $pythonu nn; regsub N $ nn $pythonn n; puts $n; regsub -all [format %c 39] $pythonb [format %c 34] bb; regsub B $pythonb $bb b; puts $b";print r(r(r(tclb,sqs,sQs),sds,sDs),d,q)}; put s $pythonu; regsub -all [format %c 39] $pythonn [format %c 34] ndouble; regsub U $ndouble $pythonu nn; regsub N $nn $pythonn n; puts $n; regsub -all [format % c 39] $pythonb [format %c 34] bb; regsub B $pythonb $bb b; puts $b';print r(r(r (tclb,sqs,sQs),sds,sDs),d,q) Authors: Andy Harter, Tristan Richardson, and Quentin Stafford-Fraser Note: Python-tcl def a(b): q="'"; print "puts {"+b; print "a("+q+q+q+b+q+q+q+")}" a('''def a(b): q="'"; print "puts {"+b; print "a("+q+q+q+b+q+q+q+")}"''') Authors: Andy Harter, Tristan Richardson, and Quentin Stafford-Fraser Note: Tcl-Python proc a {b} {set q '; puts "print $q$q$q$b; a {$b}$q$q$q"}; a {proc a {b} {set q '; puts "print $q$q$q$b; a {$b}$q$q$q"}} Author: bmckeon@unix1.tcd.ie (Brendan McKeon) Notes: procudes C file rep.c, which is compiled to give a.out, which is run to produce a copy of the original script. Must be run from the current directory, or with a 'qualified' pathname, such as "../rep.sh" or "bin/rep.sh". It prpbably won't work if you have it on your PATH and run it from a different directory - as it uses its argv[0] to open itself for input to build the C program. #!/bin/sh echo 'main(){printf("%s","'`sed 's/["\\\\]/\\\\&/g;s/$/\\\\n/'\ <$0|tr -d '\\012'`'");}'>rep.c;cc rep.c&&./a.out