
/*
 Flippo

 Dit programma vindt oplossingen van de 'Flippo' puzzeltjes
 Van 4 getallen moet je 24 maken, door ze allen precies 1 keer
 te gebruiken in een sommetje met slechts + - * /

 Het probeert gewoon alles uit. En vaak zelfs te veel doordat het niet rekening
 houdt met:
 -commutativiteit en associativiteit van + en *
 -vaker voorkomen van hetzelfde cijfer
  (8 8 3 3 geeft zodoende 4 gelijke oplossingen)

 6 (7) februari 1996
*/
#include <stdio.h>
#define floatt double

// default waarden:
int in[4]={8,8,3,3};
int uit=24;
floatt fout=0.01;


floatt op(floatt x, floatt y, int o)
  { switch (o)
        { case 0: return x+y;
          case 1: return x-y;
          case 2: return x*y;
          case 3: if (y!=0) return x/y; else return 10000;
          default: return 0;
        }
  }
char ops[4]={'+','-','*','/'};

floatt abs(floatt x) { if (x<0) return -x;
                        else return x;  }


int main(int argc, char *argv[])
{ if (argc>1)
  if (argv[1][0]=='h')
        {printf(" Michiel Meeuwissen -- februari 1996 \n\n"
                "  Gebruik %s [i] [j] [k] [l] [uitkomst] [fout] \n"
                "  met: i,j,k,l en 'uitkomst' integers.\n"
                "       en 'fout' een float\n",argv[0]);
         return 1;
        }
  for(int arg=1; arg<argc; arg++)
        { if (arg<=4) sscanf(argv[arg],"%i",&in[arg-1]);
          if (arg==5) sscanf(argv[arg],"%i",&uit);
          if (arg==6) sscanf(argv[arg],"%lf",&fout);
        }
/*
 Te verkoming van gepruts en ter nutte van de snelheid hier alle
 permutaties van 4 getallen.
 Jammer dat dit slecht te generaliseren is tot bv. 5 getallen.....
 (dan toch beter loops bedenken)
*/
        int perm[24][4]={{0,1,2,3},
                   {0,1,3,2},
                   {0,2,1,3},
                   {0,2,3,1},
                   {0,3,1,2},
                   {0,3,2,1},
                   {1,0,2,3},
                   {1,0,3,2},
                   {1,2,0,3},
                   {1,2,3,0},
                   {1,3,0,2},
                   {1,3,2,0},
                   {2,0,1,3},
                   {2,0,3,1},
                   {2,1,0,3},
                   {2,1,3,0},
                   {2,3,0,1},
                   {2,3,1,0},
                   {3,0,1,2},
                   {3,0,2,1},
                   {3,1,0,2},
                   {3,1,2,0},
                   {3,2,0,1},
                   {3,2,1,0}};

int n[4]; //hier staat de permutatie van de getallen in die bekeken wordt.
int i,j; // i: permutaties j: el. van permutatie
int o1,o2,o3; //: waarden van de 3 operatoren. 4^3 mogelelijkheden.
floatt u1,u2,u3,u4,u5; //:uitkomsten bij de 5 verschillende haakjesplaatsingen.

int max=13;
int min=0;
int w,x,y,z;
int opl=0;
for (w=min; w<max; w++)
 for (x=w; x<max; x++)
   for (y=x; y<max; y++)
     for (z=y; z<max; z++)
{ in[0]=w;in[1]=x;in[2]=y;in[3]=z;
  opl=0;
  for (i=0; i<24; i++)
    { // if (opl>0) break;
      for(j=0; j<4; j++) n[j]=in[perm[i][j]];
      for (o1=0; o1<4; o1++)
      for (o2=0; o2<4; o2++)
      for (o3=0; o3<4; o3++)
      { u1=op(op(op(n[0],n[1],o1),n[2],o2),n[3],o3);
        if (abs(u1-uit)<fout) opl++;
        //              printf("((%i %c %i) %c %i) %c %i = %f\n",
        //               n[0],ops[o1],n[1],ops[o2],n[2],ops[o3],n[3],u1);
        u2=op(op(n[0],op(n[1],n[2],o2),o1),n[3],o3);
        if (abs(u2-uit)<fout) opl++;
         //             printf("(%i %c (%i %c %i)) %c %i = %f\n",
         //              n[0],ops[o1],n[1],ops[o2],n[2],ops[o3],n[3],u2);
        u3=op(op(n[0],n[1],o1),op(n[2],n[3],o3),o2);
        if (abs(u3-uit)<fout) opl++;
         //             printf("(%i %c %i) %c (%i %c %i) = %f\n",
         //              n[0],ops[o1],n[1],ops[o2],n[2],ops[o3],n[3],u3);
        u4=op(n[0],op(op(n[1],n[2],o2),n[3],o3),o1);
        if (abs(u4-uit)<fout) opl++;
         //             printf("%i %c ((%i %c %i) %c %i) = %f\n",
         //              n[0],ops[o1],n[1],ops[o2],n[2],ops[o3],n[3],u4);
        u5=op(n[0],op(n[1],op(n[2],n[3],o3),o2),o1);
        if (abs(u5-uit)<fout) opl++;
          //            printf("%i %c (%i %c (%i %c %i)) = %f\n",
          //             n[0],ops[o1],n[1],ops[o2],n[2],ops[o3],n[3],u5);

      }
   }
if (opl>0) printf(" %2i  %2i  %2i  %2i   (%i)\n",w,x,y,z,opl);
}
printf("ready.\n");
}
