#include #include #include #define Pi 3.141592653589 #include "plist.c" typedef struct { word w; // Stores the word int count[3]; // signed sum of occurances of each letter int mod2; // matrix m; double interval[2]; } pal_word; void pal_word_destroy(w) pal_word *w; { word_destroy(&(w->w)); } void pal_word_copy(w,new) pal_word *w,*new; { word_copy(&(w->w),&(new->w)); new->count[0]=w->count[0]; new->count[1]=w->count[1]; new->count[2]=w->count[2]; new->mod2=w->mod2; new->m.m[0][0]=w->m.m[0][0]; new->m.m[0][1]=w->m.m[0][1]; new->m.m[0][2]=w->m.m[0][2]; new->m.m[1][0]=w->m.m[1][0]; new->m.m[1][1]=w->m.m[1][1]; new->m.m[1][2]=w->m.m[1][2]; new->interval[0]=w->interval[0]; new->interval[1]=w->interval[1]; } void pal_word_empty(w) pal_word *w; { w->count[0]=w->count[1]=w->count[2]=0; w->w.first=w->w.last=NULL; w->w.l=0; w->mod2=1; w->m.m[0][0]=1; w->m.m[0][1]=0; w->m.m[0][2]=0; w->m.m[1][0]=0; w->m.m[1][1]=1; w->m.m[1][2]=0; w->interval[0]=0; w->interval[1]=1; } void pal_word_addLetter_r(w,i,r) pal_word *w; int i; reflection *r; { if (w->w.last!=NULL){ // theres is at least one letter w->w.last->next=(Pletter) malloc (sizeof(struct pletter)); //pword_alloc++; w->w.last->next->l=i; w->w.last->next->next=NULL; w->w.last->next->prev=w->w.last; w->w.last=w->w.last->next; } else { // the first letter w->w.last=(Pletter) malloc (sizeof(struct pletter)); //pword_alloc++; w->w.last->l=i; w->w.first=w->w.last; w->w.last->next=NULL; w->w.last->prev=NULL; } w->count[i]+=w->mod2; w->mod2*=-1; w->w.l++; timesEquals(&(w->m), &(r->m[i])); } // The first letter is assumed to be the letter of symmetry int pal_balance(w) pal_word *w; { double ret=0; if (w->w.l==1) return 2; if (w->w.first->l==w->w.last->l){ if (w->w.l%2==0) { if (w->count[0]<0) ret-=w->count[0]; else ret+=w->count[0]; if (w->count[1]<0) ret-=w->count[1]; else ret+=w->count[1]; if (w->count[2]<0) ret-=w->count[2]; else ret+=w->count[2]; return 2*ret; } else { w->count[w->w.last->l]--; if (w->count[0]<0) ret-=w->count[0]; else ret+=w->count[0]; if (w->count[1]<0) ret-=w->count[1]; else ret+=w->count[1]; if (w->count[2]<0) ret-=w->count[2]; else ret+=w->count[2]; w->count[w->w.last->l]++; return 2*ret; } } if (w->w.l%2==0) { if (w->count[0]<0) ret-=w->count[0]; else ret+=w->count[0]; if (w->count[1]<0) ret-=w->count[1]; else ret+=w->count[1]; if (w->count[2]<0) ret-=w->count[2]; else ret+=w->count[2]; if (ret!=0) return 2*ret; return 2; } w->count[w->w.last->l]--; if (w->count[0]<0) ret-=w->count[0]; else ret+=w->count[0]; if (w->count[1]<0) ret-=w->count[1]; else ret+=w->count[1]; if (w->count[2]<0) ret-=w->count[2]; else ret+=w->count[2]; w->count[w->w.last->l]++; if (ret!=0) return 2*ret; return 2; } int main(){ int DEPTH,edge[3],e; pcomplex tri, temp; word_link SUCCEED; triangle T,Ttemp; pal_word *TRY, *w; word new; int TRY_l,bal,i,j; reflection r; double d; Pletter l,l2; SUCCEED=NULL; fscanf(stdin,"%lf",&(tri.x)); // the first angle of our triangle fscanf(stdin,"%lf",&(tri.y)); // the second angle of our triangle fscanf(stdin,"%d",&DEPTH); // the depth to search to //fscanf(stdin,"%d",&edge[0]); // check w/ symmetric side 1? //fscanf(stdin,"%d",&edge[1]); // check w/ symmetric side 2? //fscanf(stdin,"%d",&edge[2]); // check w/ symmetric side 3? edge[0]=edge[1]=edge[2]=1; TRY=(pal_word *)malloc(DEPTH * sizeof(pal_word)); for (e=0; e<3; e++){ // current edge of symmetry if (edge[e]){ // Setup triangle if (e==0) { T=triangle_make2(tri); } else if (e==1){ temp.x=tri.y; temp.y=2-tri.x-tri.y; Ttemp=triangle_make2(temp); T.z[0]=Ttemp.z[2]; T.z[1]=Ttemp.z[0]; T.z[2]=Ttemp.z[1]; } else { //e==2 temp.x=2-tri.x-tri.y; temp.y=tri.x; Ttemp=triangle_make2(temp); T.z[0]=Ttemp.z[1]; T.z[1]=Ttemp.z[2]; T.z[2]=Ttemp.z[0]; } reflect_from_triangle(T,&r); // stores the matrices of reflections TRY_l=1; pal_word_empty(&TRY[0]); pal_word_addLetter_r(&TRY[0],e,&r); while (TRY_l>0){ w=&(TRY[TRY_l-1]); //word_print_file(stdout,&(w->w)); if ((bal=pal_balance(w))==0) { word_copy(&(w->w),&new); // make from palindrome form into standard form l=new.last; l2=new.first; while ((l!=new.first)&&(l->l==l2->l)){ l=l->prev; l2=l2->next; } if (l->ll) { // incorrect order l=new.last; // reverse the word order l2=new.first; for (i=0; il; l->l=l2->l; l2->l=j; l=l->prev; l2=l2->next; } } l=new.last->prev; for (i=new.l-2; i>0; i--) { word_addLetter(&new,l->l); l=l->prev; } SUCCEED=word_insert(SUCCEED,&new); fprintf(stderr,"HOORRAY!!!\n"); pal_word_destroy(w); TRY_l--; } else if ((bal=pal_balance(w))-(DEPTH-2*w->w.l+2)>0){ pal_word_destroy(w); TRY_l--; } else { temp=eucTimes(&(w->m),T.z[w->w.last->l]); d=temp.x; //printf("new pount = (%lf,%lf) between %lf and %lf\n",d,temp.y, // w->interval[0],w->interval[1]); if (dinterval[0]){ if (w->w.l%2==0){ pal_word_addLetter_r(w,(w->w.last->l+1)%3,&r); } else { pal_word_addLetter_r(w,(w->w.last->l+2)%3,&r); } } else if (d>w->interval[1]){ if (w->w.l%2==0){ pal_word_addLetter_r(w,(w->w.last->l+2)%3,&r); } else { pal_word_addLetter_r(w,(w->w.last->l+1)%3,&r); } } else { pal_word_copy(w,&(TRY[TRY_l])); if (w->w.l%2==0){ pal_word_addLetter_r(w,(w->w.last->l+2)%3,&r); pal_word_addLetter_r(&(TRY[TRY_l]),(TRY[TRY_l].w.last->l+1)%3,&r); } else { pal_word_addLetter_r(w,(w->w.last->l+1)%3,&r); pal_word_addLetter_r(&(TRY[TRY_l]),(TRY[TRY_l].w.last->l+2)%3,&r); } w->interval[1]=d; TRY[TRY_l].interval[0]=d; TRY_l++; } } } } } word_link_print_file(stdout, SUCCEED); word_link_destroy(SUCCEED); return 0; }