Spinning Quine
Update
After completing this page/project I did a web search for my spinning
quine page. It turns out, someone else had a very similar idea. They made a
"spiraling" quine in perl. I guess great minds think alike ;-). Any ways,
here is a link to the
page with the spiraling quine. It is a lot different than mine, because they
made use of perl's ability to evaluate a string as code. Something you can't
do in C (unless you write your own interpreter). So, the code ends up being
much smaller.
Introduction
After completing a simple quine, I decided to try something a bit more
challenging. The result is the following iterating quine. An iterating quine
is a program that outputs the source code of another program. The new program
can then be compiled, and it outputs the source code for another program. This
process can be continued until eventually the n'th program outputs the original
program.
Here is the source code for the first program in the sequence. If you look
at the sequence of programs generated, the spiral of text in the array can
be seen "spinning" clock-wise.
Source: spinningquine.c char r[]=
" - SPIRAL - A~G w 77AG h 24A "
" an Iterating Quine x+y*w];}AR i{F x,y;F p;E c;} G s (w* "
" by Dave Cope ){L &p[ ;A}AF *x=&i->x;AF *y=& p[2];A h)AG "
" x,E y =1.0f;AL v;Ai->c++;A}AK q(N i->y;AF E ix( m 96 "
" p,E Ai->y x=u;A*y= s);Ap[0].c=p *p)A{A u=*x F x) 4AN "
" a(N* .0f; ));A* ];AH(b,r, q(b) [1].c=m; E i=0 ;AF {L( *d[ "
" N* x=0 (*y b[s 0].y));A}A ;AM(B;CnB) At(1) ;AD; v=*y E)( ]= "
" ;AA i-> =iy 0;AN iy(p[ ,ix(p[0].x),iy(p[0 ;A}AE ;AD; i<s ;A (x A{ "
" A} p= v)= i= x), =*a(r .y));ATc>=65&& ].y) O( i< ;i F +1 A "
" B, -> y( AE 0]. ;Ac p[0] c<=9 );A )A =m ++ a; .0 BC "
" U Ai &i A{ p[ 0) iy( 0) }Q {A +1 )A AS f) n "
" AB ; & ) ( ( ), M( c! E 0 { A * B,"
" , 1 ) ( x t x. A} [d 1= ; A { /w BA"
" BT =c x* v i, A{ ]0 A; 6-c 62 =i +i E iA 2 C "
" BA >- (x KA r( SA [p( 0 LA}A; PA;)]5 QA;) A;m )+ =t >- ;) BB "
" ,B iA i= }A a*= ;m=c xi,r(a )c(U {A)i-- ;c N A{A w%i p A} A, "
" SB {A =)u }A; ))y. .]0[pA *=cA;)0(tA NB(MA )0(t TA; =+ i E CB "
" A,B ) m (xi )BnCB ]1[p(y ;)(vA;)BnC=][r )1(tA; t! 00.0 F(y ,BC "
" RBA == Q}A; CB(MA i,)x.]1[p(xi,b(a*A; B'(UA) A;f1 )y DBA "
" ,BQB c>-i )p>-i( ))1-w(==tTA;)]i[p(UA;)' 36(=a )E(L{ BA,B "
" A,BP TA;]b J*a=vA;)p>-i( uA;36/)p>-i - f0.1(( BA,BE "
" BA,BOB [p&=i* i R I*a= };)2/h*)y- GBA,BF "
" A,BNBA,BM A{A) b E (t KA BA,BHBA,B "
" BA,BLBA,BKBA,BJBA,BI "
;
#define w 77
#define h 24
#define s (w*h)
#define m 964
char *d[]=
{
"\n",
"\"",
"\\",
"for(",
"int",
"float",
"#define",
"memcpy",
"sin",
"cos",
"void",
"return",
"printf",
"char",
"main",
"else",
"while(",
"struct",
"do",
"if(",
"putchar",
};
char*a(char*p,int x,int y){return &p[x+y*w];}
struct i{float x,y;float p;int c;} p[2];
int ix(float x){return(int)((x+1.0f)*w/2);}
int iy(float y){return(int)((1.0f-y)*h/2);}
void t( int b )
{
struct i *i=&p[b];
if( i->c == m )
{
i->c=1;
i->p=i->x=0.0f;
i->y=1.0f;
return;
}
float *x=&i->x;
float *y=&i->y;
float u=*x;
float v=*y;
float a;
do
{
i->p += 0.001f;
a=(63 - i->p)/63;
u=a*sin(i->p);
v=a*cos(i->p);
}while(ix(u)==ix(*x)&&iy(v)==iy(*y));
*x=u;
*y=v;
i->c++;
}
void q(char *p)
{
int i=0;
for(;i<s;i++)
{
int t=i%w;
if( !t )
putchar('"');
putchar(p[i]);
if(t==(w-1))
printf("\"\n");
}
}
void v()
{
int i=0;
char b[s];
memcpy(b,r,s);
p[0].c=p[1].c=m;
t(1);
for(;i<=m+10;i++)
{
t(0);
t(1);
*a(b,ix(p[1].x),iy(p[1].y))=*a(r,ix(p[0].x),iy(p[0].y));
}
q(b);
printf(";\n");
}
int main()
{
int i=m;
char c;
printf("char r[]=\n");
v();
p[0].c=m;
do{
t(0);
c=*a(r,ix(p[0].x),iy(p[0].y));
}while(c!=126);
while(--i)
{
t(0);
c=*a(r,ix(p[0].x),iy(p[0].y));
if(c>=65&&c<=90)printf(d[c-65]);
else putchar(c);
}
return 0;
}
Note: The source code in the figure above has been indented. Take a look
at the original source to see the unmodified
formatting.
|