#include <stdio.h>
#include <math.h>
#define TRUE  1
#define FALSE 0

FILE *fout,
     *fin;
main() {
  void  set_pi_vector(),             insert(),
        divide_pi(),                 delete(),
        mesh(),
        permute(),
        write_vec(),
        fswap();
  float pi[8],
        ind[8],
        dup[8];
  int   i,j,duplen=0, indlen=0, findocc();

  fin=fopen("/mit/smmadana/value.dat","r");
  fout=fopen("/mit/smmadana/perm.dat","w");
  for(i=0;i<40;i++) {
    if(i==13) {
      fclose(fout);
      system("mv perm.dat perm1.dat");
      fout=fopen("/mit/smmadana/perm.dat","w");
    }
    if(i==26) {
      fclose(fout);
      system("mv perm.dat perm2.dat");
      fout=fopen("/mit/smmadana/perm.dat","w");
    }
    for(j=0;j<8;j++) 
      ind[j]=dup[j]=0;
    duplen=indlen=0;
    set_pi_vector(pi);
    divide_pi(pi,ind,&indlen,dup,&duplen);
    permute(ind,indlen-1,dup,duplen,indlen);
  }
  fclose(fout);
  fclose(fin);
}
/*****************************************************************************/
void set_pi_vector(pi)
float pi[8]; {
  int j;
  for(j=0;j<8;j++) {
    fscanf(fin,"%f ",&pi[j]);
    printf("%4.2f ",pi[j]);
  }
  printf("\n");
}
/*****************************************************************************/
void divide_pi(pi,ind,indlen,dup,duplen)
float pi[],
      ind[],
      dup[]; 
int   *duplen, *indlen; {
  int i,j,match;

  ind[0]=pi[0];
  *indlen=1;
  for(i=1;i<8;i++) {
    j=0;
    match=FALSE;
    while((!match)&&(j<*indlen)) {
      if(ind[j]==pi[i])
        match=TRUE;
      j++;
    }
    if(match) {    
        dup[*duplen]=pi[i];
        *duplen= *duplen + 1;
    }
    else {
      ind[*indlen]=pi[i];
      *indlen= *indlen + 1;
    }
  }
}
/*****************************************************************************/
void permute(ind,indlen,dup,duplen,veclen)
float ind[],dup[]; 
int indlen,veclen,duplen; {
  int i;

  for(i=indlen;i>(-1);i--) {
    if (indlen==0) {
      mesh(ind,veclen,dup,duplen,0);}
    else {
      fswap(&ind[i],&ind[indlen]);
      permute(ind,indlen-1,dup,duplen,veclen);
      fswap(&ind[i],&ind[indlen]);
    }
  }
}

/*****************************************************************************/
void mesh(ind,indlen,dup,duplen,slot)
float ind[],dup[];
int   duplen,indlen; {
  int i, dupocc=0, indocc=0;

  i=0;
  dupocc=findocc(dup,slot);
  while(i<indlen) {
    if(dup[slot]==ind[i]) indocc++;
  
    if((dup[slot]!=ind[i])&&(dupocc==indocc)) {
      insert(ind,&indlen,dup[slot],i);
      if(slot+1<duplen)
        mesh(ind,indlen,dup,duplen,slot+1);
      else
        write_vec(ind,indlen);
      delete(ind,&indlen,i);
    }
    i++;
  }
  if((i==indlen)&&(i!=8)) {
    ind[i]=dup[slot];
    indlen++;
    if(slot+1<duplen)
      mesh(ind,indlen,dup,duplen,slot+1);
    else
      write_vec(ind,indlen);
    indlen--;
  } 
}
/*****************************************************************************/  
void insert(vec,len,val,slot)
float vec[], val;
int slot, *len; {
  int i;

  for(i= *len-1;i>slot-1;i--)
    vec[i+1]=vec[i];
  vec[slot]=val;
  *len= *len+1;
}
/*****************************************************************************/
void delete(vec,len,slot)
float vec[];
int slot, *len; {
  int i;
  
  for(i=slot;i<(*len-1);i++)
    vec[i]=vec[i+1];
  *len= *len - 1;
}
/*****************************************************************************/
void fswap(x,y)
float *x,*y; {
  float temp;

  temp= *x;
  *x= *y;
  *y= temp;
}
/*****************************************************************************/
void write_vec(vec,len)
float vec[];
int len; {
  int i;
  
  for(i=0;i<len;i++) {
    fprintf(fout, "%1.1f ",vec[i]);}
  fprintf(fout,"\n");
}
/*****************************************************************************/
int findocc(vec, slot)
float vec[];
int slot; {
  int i, count=1;

  for(i=0;i<slot;i++) {
    if (vec[i]==vec[slot]) 
      count++;
  }
  return(count);
}
/*****************************************************************************/
