SEclone  subroutines of the main routine

 

Before entering in the search of the solutions, it’s time to deliver the 2 subroutines of the “main” function.

The code is located here

 

#include "c\_00_  Batch_Start.cpp" // main routine initial and command line parsing

#include "c\_00_  Batch_Go.cpp"    // main routine processing puzzles

 

 

 

Nothing very exiting to tell about them.

 

The first one  Batch_Start

 

Parse the command line and store the options in the options handler “o$”,

Write the summary of options on “cout”

Open all input and output files

In case open of any file fail, a return code is sent to cancel the task.

 

 

The second one Batch_Go

 

Compute and print the overall elapsed time

Get all puzzles in an endless loop (while())

For each puzzle

 Compute and print the elapsed time

 Check the puzzle for structural validity

 Check for uniqueness and store the solution

 Call the solving routine

 Print the results

 

 

// Batch Start

// routines calles by "Main" and specific functions used

//==== specific data

char finput_name[128]; // string file names if given

char * version="V0.0 dated October 2010";

 

// =====================functions written below

 

int Convert_String_to_string(char * str,System::String  ^Str);

int Search_ccd(char * ww,int n);  // search commands 2 or 3  bytes

int Search_long(char * ww);   // search for extended commands eg: input=FILE

int GetRating(char * z);     // look for xx.y

void Filter_quasi_ed(char * ww); // finish command -n(?)>

 

//==========================================

// Batch_Start analyzing the command line and initial of the batch

// look for commands

// Open input output

// makes all batch initialisations

 

int Batch_Start(array<System::String ^> ^args)

{char ww[512];

 cout <<"Version: "<< version<<endl;

 int narg=args->GetLength(0);

 for(int i=0;i<narg;i++)

 {

 if(!Convert_String_to_string(ww,args[i]))continue;// ignore if error

 int ir=Search_ccd(ww,3),val1;  if(ir>=0)

 {if(o$.o1 && o$.o1<3) continue; // ignored if -d -p

  o$.o1=3; // special filter on

  if(ir<5) {val1=GetRating(&ww[3]);

            if (val1<0) continue;}

       switch (ir)

     {case 0:o$.maxed=val1; break//-d<

         case 1:o$.mined=val1; break//-d>

      case 2:o$.maxep=val1; break//-p<

         case 3:o$.minep=val1; break//-p>

      case 4:o$.maxer=val1; break//-r<

      case 5:Filter_quasi_ed(ww);   break// -n(?)>

     }

       continue;// don't try command 2

    }// end command 3 bytes

 ir=Search_ccd(ww,2);  if(ir>=0)

 {if(ir==8) ir=Search_long(&ww[2]);  //"--"

  if(ir>=0)

  switch (ir)

     {case 0:o$.o1=1; break//-d

         case 1:if(o$.o1-1)o$.o1=2; break//-p

 

         case 2: if(ww[1]=='-')strcpy_s(finput_name,128,&ww[8]); 

                       else  strcpy_s(finput_name,128,&ww[2]);

                    finput.SetName(finput_name);

                       cout <<"input asked   "<<finput_name<<endl;break//-i

 

         case 3: o$.ptime=1; break//-e

         case 4: o$.ot=1;E$.pron=1; break//-t

 

     }

 

  }// end command 3 bytes

 

 

 }

if(o$.pctl()) return 0;//control of option on console

 

if(finput.OpenFI()) return 0; // 1 if error open

if(foutput.OpenFO1()) return 0; // 1 if error open

if(se_refus.OpenFO2()) return 0; // 1 if error open

    

return 1;

}

 

//========================================

// try to locate a command length n

int Search_ccd(char * ww,int n)

{char * ccd3[]={"-d<" , "-d>" , "-p<" , "-p>" , "-r<" , "-n("      };

 char * ccd2[]={"-d""-p" , "-i" ,   "-e" , "-t" ,"--"  };

 char wt[4]; strncpy_s(wt,4,ww,n);wt[3]=0;

 for(int i=0;i<((n==2)?6:6);i++)

        if(!strcmp(wt,(n==3)?ccd3[i]:ccd2[i])) return i;

return -1;}

 

//=============================================

int Search_long(char * ww)

{char * cc[]={"diamond""pearl" , "input=" , "split=" ,

               "elapsed" , "test"   };

 char wt[20];

 for(int i=0;i<6;i++)

 {int j=strlen(cc[i]);

  for(int k=0;k<i;k++)wt[k]=ww[k];   ww[j]=0;

  if(!strcmp(wt,cc[i])) return i;}

return -1;}

 

//=================================================

int GetRating(char * z)

{int val=0;

if(z[0]<'1' || z[0]>'9') return -1;

val=z[0]-'0';

if(z[1]-'.') {if(val-1) return -1;

               if(z[1]<'0' || z[1]>'1') return -1;  //10.x or 11.x

                        val=10*val+z[1]-'0';z++;} //skip one position in inflow

if(z[1]-'.')return -1;// now must be the '.'

if(z[2]<'0' || z[2]>'9') return -1;

val=10*val+z[2]-'0'// now val is in the range 010 to 120 for 1.0 to 11.9

return val;}

 

//========================================

 

// Converting a String unicode to a classical string

 

int Convert_String_to_string(char * str,System::String  ^Str)

{pin_ptr<const wchar_t> wch = PtrToStringChars(Str);

 size_t convertedChars = 0;

 size_t  sizeInBytes = ((Str->Length + 1) * 2);

 errno_t err = 0;

 err = wcstombs_s(&convertedChars, str, 512,  wch, sizeInBytes);

 if (err != 0)return 0;

 return 1;

}

//===========================================

void Filter_quasi_ed(char * z) // finish command -n(?)< and command -n(?)>

{if(z[2]<'2' || z[2]>'9') return ;

 int w=GetRating(&z[4]);

 if(w<40 || w>110) return;

 o$.edcycles=z[2]-'0';o$.miner=w;

}

 

 

=====================================

=====================================

 

 

// loop to process the batch and puzzles verifications

 

// local functions

long GetTimeMillis();                       // get   standard time in millisec

void PrintTime(long ts,long te,int cons=0);    // Print elapsed time

int Puz_Go(char *ze);                       // processing a puzzle

 

 

void Batch_Go()

{long tstart=GetTimeMillis();// for the overall elapsed time

char ze[82];foutput.zpuz=ze;

while(finput.GetPuzzle(ze))

  {long tpuz_start=GetTimeMillis();

   Puz_Go(ze); o$.PrintErEpEd(); // result

   if(o$.ptime && o$.ermax>=10 && o$.ermax<=120 )

         {long tpuz_end=GetTimeMillis();

          PrintTime(tpuz_start,tpuz_end);}

  

   if(o$.ermax<10 || o$.ermax>120) se_refus << endl; else  foutput<<endl;

  }

 long tend=GetTimeMillis();

 PrintTime(tstart,tend,1);  foutput<<endl;

}

// processing a puzzle

int Puz_Go(char *ze)

{char * d=jdk.gg.pg; // final location for the normalized puzzle

 for(int i=0;i<81;i++) //get normalised puzzle in puz

   if(ze[i]-'.') d[i]=ze[i]; else  d[i]='0';

 if (!jdk.Check()) {foutput.PrintErEpEd(0,0,01);return 0;} // invalid structure no solution

 int ir=un_jeu.Unicite(jdk.gg);

 if( ir-1) {foutput.PrintErEpEd(0,0,02);return 0;} // not  one solution

 // the solution is stored in an appropriate form

 // to check later the validity of eliminations

 for(int i=0;i<9;i++) jdk.csol[i].Init();

 for(int i=0;i<81;i++) jdk.csol[jdk.solution[i]-'1'].Set(i);

 

 jdk.Traite(); // go to standard processing

 

return 1;}

 

 

// catching time as seconds+millis  (seconds since year 1970)

long GetTimeMillis()

{struct _timeb tbuf;    _ftime64_s(&tbuf);

 return ((long)(1000*tbuf.time)+tbuf.millitm);}

 

// builing an appropriate message depending on the elapsed time te-ts

void PrintTime(long ts,long te,int cons)

{UINT dt=te-ts,dtmil=dt%1000,dts=dt/1000,dth=dts/3600;   dth=dth%1000;

if(cons)

   { cout << endl<<"total elapsed time ";

     UINT dtm=dts/60; dts=dts%60 ,   dth=dtm/60, dtm=dtm%60;

     if(dth) cout <<dth<<"h ";

        if(dth || dtm) cout <<dtm<<"m ";

     cout   <<dts <<"s ";

        if(dtmil<10) cout << "00"; else  if(dtmil<100) cout << '0';

        cout <<dtmil<<"ms ";   return;

    }

  foutput   <<";"<<dts <<".";

  if(dtmil<10) foutput << "00"; else  if(dtmil<100) foutput << '0';

  foutput <<dtmil<<"s "

}