BEWARE - HTML INTERPRETATION DOES WEIRD THINGS TO THE
COMPRESSED VERSIONS OF THE CODE .... DO NOT ASSUME THAT
WHAT APPEARS ON YOUR SCREEN IS PRECISELY THE RIGHT THING!
/* the entry is included first, followed by the equivalent expansion
#define Q define
#Q V(f,w) u[a[f]]w;u[a[f+1]]w;
#Q C(f) if(u[a[f+1]]||a[f]==a[f+1])continue;V(f,++)
#Q L(j,r,s,v,z) a[j]=10;while(a[j]--){if(u[a[j]])continue;a[j+1]=((r=s+v*a[j])/v)%10;C(j)z V(j,--)}
#Q T 10000
main(y,F)int*F;{int x,d,c,A,u[10],a[10],m,n,o,p;F=fopen(F[1],"r");while(-1-fscanf(F,"%d%d",&A,&p)){d=T*T;y=T-(A-p)%T;if(T/2<(x=abs(A-p)%T))x=T-x;if(!(x%10)||x<25||x%1000<3||x%1000>997||abs(x-100)<3||abs(x-200)<2)d=~0;else for(x=A/T;d>691999;x++){a[8]=x%10;a[9]=(x/10)%10;C(8)L(0,m,y,1,L(2,n,m,10,L(4,o,n,100,L(6,p,o,1000,c=p-y+a[8]*T+a[9]*T*10-A;if(c<0)c+=T*100;if(c
main(argc,argv)
int argc;
char **argv;
{
int x,distance,c,A,B,used[10],a[10],m,n,o,y,p;
FILE *F;
if(NULL==(F=fopen(argv[1],"r"))){
fprintf(stderr,"Cannot read %s\n",argv[1]);
exit(1);
}
while(EOF!=fscanf(F,"%d%d",&A,&B)){
distance=10000*10000;
y=10000-(A-B)%10000;
/*Some [A,B] pairs have no solution. This is a function of (A-B)%10000.
*These rules were determined empirically
*I tried to find more compact representation of this formula,
*but failed.
*/
x=abs(A-B)%10000;
if(5000997||abs(x-100)<3||abs(x-200)<2) {
distance= -1;
}else {
/* By entering this loop, I am guaranteed to have a solution.
* Solution will be <=691999, always.
*
*a[9] a[8] a[6] a[4] a[2] a[0] = A
* a[7] a[5] a[3] a[1] = B
*
*Basic scheme is to pick a[9],a[8] (starting at current value),
*then construct all solutions right-to-left. NOTE, we continually
*use the fact that (A-B)%10000 remains constant as we roll along.
*We use continue a lot to short circuit impossible branches.
*Thus:
* choose an a[0] (8 values possible), this immediately determines a[1]
* choose an a[2] (6 values possible), there may or may not
* be an a[3] which
* works for each a[2]
* etc. for a[4], a[6]
*If we find any solution within a 10K-ade, we don't need to
*go further, just accept the smallest solution.
*The array used[] keeps track of which digits are currently
*in use.
*/
for(x=A/10000;distance>691999;x++){
a[8]=x%10;
a[9]=(x/10)%10;
/*In the next statement, used[a[9]] is not useful, it was
*kept in to show the pattern which continues below.
*/
if(used[a[9]]||a[8]==a[9])continue;
used[a[8]]++;
used[a[9]]++;
/*I used
* a[0]=10;while(a[0]--)
*rather than
* for(a[0]=0;a[0]<10;a[0]++)
*simply to save a few bytes.
*/
a[0]=10;
while(a[0]--){
if(used[a[0]])continue;
m=y+1*a[0];
a[1]=m%10;
if(used[a[1]]||a[0]==a[1])continue;
used[a[0]]++;
used[a[1]]++;
a[2]=10;
while(a[2]--){
if(used[a[2]])continue;
n=m+10*a[2];
a[3]=(n/10)%10;
if(used[a[3]]||a[2]==a[3])continue;
used[a[2]]++;
used[a[3]]++;
a[4]=10;
while(a[4]--){
if(used[a[4]])continue;
o=n+100*a[4];
a[5]=(o/100)%10;
if(used[a[5]]||a[4]==a[5])continue;
used[a[4]]++;
used[a[5]]++;
a[6]=10;
while(a[6]--){
if(used[a[6]])continue;
p=o+1000*a[6];
a[7]=(p/1000)%10;
if(used[a[7]]||a[6]==a[7])continue;
used[a[6]]++;
used[a[7]]++;
c=p-y+a[8]*10000+a[9]*10000*10-A;
if(c<0)c+=10000*100;
if(c-->