Jean-Luc Baril, Vincent Vajnovszki
Gray Code for Derangements
to appear in Discrete Applied Mathematics,
Abstract
#include
int D[20],pred[20],succ[20],Nb=1,head,tail,m;
/******************************************/
rem_ove(int r)
{ if( r==head )
head=succ[r];
else { if( r==tail )
tail=pred[tail];
else { succ[pred[r]]=succ[r];
pred[succ[r]]=pred[r];
}
}
} /******************************************/
append(int r)
{ if( rtail )
tail=r;
else { succ[pred[r]]=r;
pred[succ[r]]=r;
}
}
}/******************************************/
type()
{ int i;
printf("%d\t",Nb++);
for (i=1;i<=m;i++) printf("%d",D[i]);
printf("%c",'\n');
}/******************************************/
init()
{ int i;
printf("donnez :"); scanf("%d",&m);
head=1;tail=m+1;
for (i=1;i< (m+1);i++) succ[i]=i+1;
for (i=2;i<=(m+1);i++) pred[i]=i-1;
for (i=1;i< m;i++) D[i]=i+1 ; D[m]=1;
type();
}/******************************************/
transp(int a, int b)
{ int aux;
aux=D[a];
D[a]=D[b];
D[b]=aux;
}/******************************************/
left (int a, int b, int c)
{ transp(a,b); transp(b,c); }/**************/
right(int a, int b, int c)
{ transp(b,c); transp(a,b);}/**************/
psi_up(int r)
{ if (r==head)
{ transp(head,succ[head]);
transp(pred[tail],tail);}
else
{ transp(pred[r],tail);
transp(r,succ[r]);
}
type();
}/******************************************/
psi_dw(int r)
{ if (pred[r]==head)
{ transp(head,succ[head]);
transp(pred[tail],tail);}
else
{ transp(pred[pred[r]],tail);
transp(pred[r],r);
}
type();
}/******************************************/
phi_up(int r)
{ right(pred[r],r,tail);type();}/*****/
phi_dw(int r)
{ left(pred[pred[r]],pred[r],tail);type();}/*******/
phi_psi(int r,int i,int n)
{ if (n==4)
{ if (i==3) transp(head,pred[tail]); else transp(r,succ[r]);}
else
{ if (i==1)
{ if ((n%2)==0)
right(head, pred[pred[pred[tail]]], pred[pred[tail]]);
else left(head, pred[pred[pred[tail]]], pred[pred[tail]]);
}
else if ( (i>=2) && (i<= (n-4)) )
{ transp(pred[r],r); transp(pred[pred[pred[tail]]],pred[pred[tail]]);
}
else if ( i== (n-3) )
right (pred[pred[pred[pred[tail]]]],pred[pred[pred[tail]]],pred[pred[tail]]);
else if ( i== (n-2) )
left (pred[pred[pred[pred[ tail ]]]],pred[pred[tail]],pred[tail]);
else if ( i== (n-1) )
{ if ((n%2)==0)
{ transp(pred[pred[pred[pred[ tail ]]]] , pred[pred[ tail ]]);
transp(pred[pred[pred[ tail ]]] , pred[tail] );}
else right(pred[pred[pred[pred[ tail ]]]], pred[pred[ tail ]] , pred[tail] );
}
}type();
}/******************************************/
psi_phi(int r,int i,int n)
{ if (n==4)
{ if (i==3) transp(head,pred[tail]); else transp(r,succ[r]);}
else
{ if (i==1)
{ if ((n%2)==0)
left(head, pred[pred[pred[tail]]], pred[pred[tail]]);
else right(head, pred[pred[pred[tail]]], pred[pred[tail]]);
}
else if ( (i>=2) && (i<= (n-4)) )
{ transp(pred[r],r); transp(pred[pred[pred[tail]]],pred[pred[tail]]);
}
else if ( i== (n-3) )
left (pred[pred[pred[pred[tail]]]],pred[pred[pred[tail]]],pred[pred[tail]]);
else if ( i== (n-2) )
right (pred[pred[pred[ pred[tail ]]]],pred[pred[tail]],pred[tail]);
else if ( i== (n-1) )
{ if ((n%2)==0)
{ transp(pred[pred[pred[pred[ tail ]]]] , pred[pred[ tail ]]);
transp(pred[pred[pred[ tail ]]] , pred[tail ]);}
else left(pred[pred[pred[pred[ tail ]]]] , pred[pred[ tail ]] , pred[tail]);
}
}type();
}/******************************************/
gen_up(int n,int t, int r)
{ int i,run;
tail=pred[tail];
if (t==1) rem_ove(r);
if (n==3) {left(head,succ[head],tail); type(); }
else
{ run=head;
for (i=1;i<=n-1;i++)
{ if ( (i%2) ==1)
{ gen_up(n-1,0,run);
phi_psi(run,i,n);
if (n>4) gen_dw(n-2,1,run);
if (i != (n-1) )
{ psi_up(run);
run=succ[run];
}
}
else
{ if (n>4) gen_up(n-2,1,run);
psi_phi(run,i,n);
gen_dw(n-1,0,run);
if (i != (n-1) )
{ phi_up(run);
run=succ[run];
}
}
}
}
if (t==1) append(r);
tail=succ[tail];
}/******************************************/
gen_dw(int n,int t, int r)
{ int i,run;
tail=pred[tail];
if (t==1) rem_ove(r);
if (n==3) { right(head,succ[head],tail); type();}
else
{ run=pred[tail];
for (i=n-1;i>=1;i--)
{ if ( (i%2) ==1)
{ if (n>4) gen_up(n-2,1,run);
psi_phi(run,i,n);
gen_dw(n-1,0,run);
if (i != 1 )
{ phi_dw(run);
run=pred[run];
}
}
else
{ gen_up(n-1,0,run);
phi_psi(run,i,n);
if (n>4) gen_dw(n-2,1,run);
psi_dw(run);
run=pred[run];
}
}
}
if (t==1) append(r);
tail=succ[tail];
}/******************************************/
main()
{ init();
if(m>=3)gen_up(m,0,0);
}