SEclone  solving basic techniques

 

The first part of the program will use additional .h and .cpp files

Here are the files we need.

 

#include "h\_04b_  tir.h"                // class for processing of locked sets and fishes

#include "h\_04d_  paires.h"

#include "h\_05a_  RIN.h"

 

#include "c\_04a_  lock.cpp"

#include "c\_04b_  ecs.cpp"

#include "c\_04c_  xw.cpp"

#include "c\_04d_  paires.cpp" 

#include "c\_04d_  xyw.cpp"

#include "c\_04d_  paires_bug.cpp" 

#include "c\_04d_  paires_bug3.cpp" 

#include "c\_04d_  paires_bug4.cpp" 

#include "c\_05b_  RI_2N.cpp"

#include "c\_05a_  RIN_el.cpp"

#include "c\_05a_  RIN_el2.cpp"

 

As already mentioned, the process for the basic moves is entirely included in jdk.cpp.

 

Candidates locked in a row/box or column/box

 

The code for candidates locked in a row, column or box is also part of jdk, but is included in the file lock.cpp.

 

 

// part of JDK class methos processing locked candidates in a box, row,col

 

void messlock(int obj,int obj2,int ch)

{if(!o$.ot) return;

int   it1=obj2/9,it2=obj/9,ii1=obj2%9,ii2=obj%9;

char c1,c2; c1= (it1-1)?(char)(ii1+'1'):lc[ii1];

                     c2= (it2-1)?(char)(ii2+'1'):lc[ii2];

E$.E("-> ");E$.E(orig[it1]);E$.E(ii1+1);E$.E("  digit ");   

E$.E(ch+1);E$.E(" in ");E$.E(orig[it2]);E$.Enl(ii2+1);

}

/* rating difficulty linked to that include

    Single_after_Locked=17,         // locked in box  do only the fix

    Locked_box=26,                          // locked in box  no fix

    Locked_RC=28,                           // locked in row/col  no fix

 

*/

 

//<<<<<<<<<<<<<<<<<<<<

int JDK::TraiteLocked(int rating)

{if(rating==26) return TraiteLocked2(18,27); // box only no fix

 if(rating==28) return TraiteLocked2(0,18); // row col  no fix

// now rating 1.7, process only boxes,

// must generate a new single in an attached box to elem2

// clearing is done in the cell where the fix takes place

 int ir=0; int ialt;

 for(int ich=0;ich<9;ich++)

 {ZINFL wf=c[ich],wfel;

   for(int iel=18;iel<27;iel++)

      { wfel=divf.elz81[iel]& wf;if( wfel.Nul())continue;

           if(divf.IsAutreObjet (wfel,iel,ialt))

            { ZINFL wa=wf&divf.elz81[ialt],wex=wa^wfel;

              if (wex.NonNul())

             // the search for singles is done only in boxes

                      // intersecting with ialt , so it must be a hidden single

                 {int ok=0;ZINFL ww;

                     for(int i=18;i<27;i++) // must be a box

                            if((i-ialt) && (divf.elz81[i]&divf.elz81[ialt]).NonNul())

                       {ww=(divf.elz81[i]&jdk.c[ich])-wex;

                         if(  ww.Count()==1)     {ok=1;  break;}

                      }

            if(ok)  // clear others candidates in the cell to be fixed

                     {messlock(ialt,iel,ich) ;

                      int i8=ww.First();T81t[i8].Keep(ich);

                      E$.Enl("lock assignment");

                      return jdk.FaitGoA(i8,ich+'1',4);}// immediate return after  assign 

                }

              }

  }}

return ir;}

 

 

 

 

//<<<<<<<<<<<<<<<<<<<<

int JDK::TraiteLocked2(int eld,int elf)

{int ir=0; int ialt;

 for(int ich=0;ich<9;ich++)

 {ZINFL wf=c[ich],wfel;

   for(int iel=eld;iel<elf;iel++)

      { wfel=divf.elz81[iel]& wf;if( wfel.Nul())continue;

           if(divf.IsAutreObjet (wfel,iel,ialt))

            { ZINFL wa=wf&divf.elz81[ialt],wex=wa^wfel;

              if (wex.NonNul())

                 {messlock(ialt,iel,ich) ;

                 T81->Clear(wex,ich);ir=1;

                 wf=c[ich]=wf^wex;   }

              }

  }}

return ir;}

 

Locked sets and hidden locked sets

 

The code for  locked sets and hidden locked sets use a new class TIR having only one member “yt”.

That class is also used for fishes solved thru a similar process

 

 

//That class is dedicated to the processing of algorithms building

//  a progressive collection of cells

// looking for locked sets

// looking for fishes.

 

// such algorithms are using  recursive routines

 

class TIR

{public:

CB9CH non,cases,wf,wi;

int rangc,rangv,e,e27,typeqc,aiggo,single,hid_dir; //0 dir,1 hidden; 2 both

OBBIEL * el;UCHAR ch;

void InitTir(CB9CH none,CB9CH casese, int rangc,int rangv);

void InitXW();

int Tiroirs(int nn,int hidden,int sing);

int UnTiroir();

int XW(int nn); 

int XW(CB9CH fd ,int iold,int irang);

int GroupeObjetsChange(int decalage,int ch);

 }yt;

 

 

In my solver, all locked sets are solved in once, same for all fishes. Here, the process is split according to SE requirements.

 

The search id done in recursive mode and 2 key CB9CH bit fields store the results, wf and wi.

One is dedicated to cells and the other to digits. The role of each is exchanged when we switch from locked set to hidden locked sets.

 

The search is made using the alternative index.

 

Here is the code to find and solve locked sets and hidden locked sets

 

 

//<<<<<<<<<<<<<<<<<<<<<   On cherche tiroir dans element  // boucle recurrente sur i

int OBBIEL::tiroir(CB9CH fd,int iold,int irang)

// on progresse sur indice et on regarde si fusion n-1  ok

 int i,id=(yt.non.f && (irang-1))? 0:iold+1;  // debut 0 avec pseudos et rang 1

 for (i=id;i<(11-yt.rangc+irang);i++)  // il doit rester des cases

  { if(eld[i].n<2 ||eld[i].n>yt.rangv) continue;

        if( yt.non.On(i))continue; //pour pseudo

        CB9CH wf=eld[i].b|fd; if (wf.QC() >yt.rangv) continue;

        if(irang==(yt.rangc-2)){yt.wf=wf;yt.wi.Set(i);

        if(wf.QC() ==yt.rangv)return 1; else return 0; }

            // une erreur a tester    on poursuit si <

       // il peut manquer des tiroirs!!!!! curieux que jamais détecté!!!!

        if(tiroir(wf,i,irang+1)){yt.wi.Set(i); return 1; }

  }

return 0;}

int TIR::Tiroirs(int nn,int hid,int sing)     //recherche normale des tiroirs

{rangv=nn;single=sing;hid_dir=hid; int ir=0;

int ied=0,ief=54;

if(!hid_dir )ief=27;if(hid_dir==1 )ied=27;if(single){ied=27;ief=54;}

  for( e=ied;e<ief;e++)   // direct, hidden or both upon request

  {rangc=rangv; non.f=cases.f=0; if(e<27) e27=e; else e27=e-27;

       if(jdk.NonFixesEl(e%27) < (rangv +1)) continue;

       for(int i=0;i<9-rangv+1;i++)

       {int nn= aztob.tpobit.el[e].eld[i].n;

        if(nn<2 || nn>rangv) continue;

              CB9CH w;w=aztob.tpobit.el[e].eld[i].b;

        wi.f=0; wi.Set(i);

        if(!aztob.tpobit.el[e].tiroir(w,i,0)) continue;

        if (UnTiroir())ir= 1;     

       } 

   }

if(ir)return 1;

return 0;}

int TIR::UnTiroir()

{// is there a single required after the locked set to accept it

 int ir=0;

 if(single) // will be covered slowly can be any element row, col, box

 { for(int i=0;i<9;i++)  if(wf.Off(i))

      {USHORT i8=divf.el81[e27][i];

       P81 p=T81t[i8];  if(p.v.typ ) continue;// must be non assigned

          CB9CH wc=p.v.cand-wi;

                 for(int j=0;j<9;j++) if (wc.On(j) )// a possible hidden digit

             {CB9CH wcd=aztob.tchbit.el[e27].eld[j].b-wf; // positions still valid

              if(wcd.QC()==1)

             {E$.Enl("ecs assignment");

                       jdk.FaitGoA(i8,j+'1',4);// stop at first assignment

                    ir=1; break;}

             }// end for j if

        

    }// end hidden ls

  if(!ir) return 0;// no single found

  }// end if single

 

 else if(e<27) {if (!jdk.ChangeSauf(e,wi,wf)&&(!ir) )return 0;  }

          else   { if (!jdk.Keep(e27,wf,wi) &&(!ir))return 0;  }

 

if(!o$.ot) return 1;

// describe the LS even if no more eliminations after an assignment

 

char *gt[]={"LS2 ","LS3 ","LS4 ","LS5 " };

 

int in=rangv-2,  it2=(e%27)/9,ii2=e%9;

 char c2= (it2-1)?(char)(ii2+'1'):lc[ii2];

E$.E("->");E$.E(gt[in]);

if(e<27)

   {E$.E(" cells ");   E$.E( wi.String());E$.E(" digits ");  }

else

 {E$.E(" digits ");E$.E( wi.String());E$.E(" cells "); }

E$.E( wf.String());E$.E(" ");E$.E(orig[it2]);E$.E(" ");E$.Enl(c2);

return 1;

}

 

 

Fishes

 

As for locked sets, fishes are solved thru the same routine.

Nothing special in SE for such moves, so this is just the code of my solver split to meet SE requirements

 

//<<<<<<<<<<<<<<<<<<<<<   On cherche XW dans lignes ou cols  boucle recurrente sur i

int TIR::XW(CB9CH fd,int iold,int irang)     // en élément i chiffre ch

{   // on progresse sur indice et on regarde si fusion n-1  ok

  for (int i=iold+1;i<9;i++)  // il doit rester des éléments

  { int nn=el[i].eld[ch].n;

        if(nn<2 ||nn>rangv) continue;

    CB9CH wfu=el[i].eld[ch].b|fd;      if (wfu.QC() >rangv) continue;

    if(irang==(rangv-2)){ if(wfu.QC() - rangv)continue;

                         wf=wfu; wi.Set(i);return 1; }

      else if(XW(wfu,i,irang+1)) {wi.Set(i); return 1; }

  }

return 0;}

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< en mode XWING liste objets et chiffres

int TIR::GroupeObjetsChange(int dobj,int ch)

{CB9CH x(ch); int ir=0;

 for(int i=0;i<9;i++)   if(wf.On(i)) ir+= jdk.ChangeSauf(dobj+i,wi,x);

return ir;}

//<<<<<<<<<<<<<<<<<<<<<<<< ici chiffre en majeur éléments en mineur

int TIR::XW(int nn)

{char *gxw[]={"XWing ","SwordFish  ","Jelly (XW4) ","Squid (XW5)  " ,

              "Whale (XW6)","Leviathan (XW7)" };

 CB9CH w; rangc=nn;

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

  {ch=(UCHAR)i;

   for(int iel=0;iel<10-rangv;iel++)

   {el=aztob.tchbit.el; int nn=el[iel].eld[i].n;

    if(nn>1 &&nn<=rangv)

    { w=el[iel].eld[i].b; wi.f=0; wi.Set(iel);

      if( XW(w,iel,0) )

       { if(GroupeObjetsChange(9,i) )  // action colonnes

            {E$.E(gxw[rangv-2]);   E$.E(" digit ");     E$.E(i+1);

             E$.E( " columns ");   E$.E(wf.String(0));

                E$.E(" rows ");  E$.Enl(wi.String());    

                return 1;        }}

       }

     el=&aztob.tchbit.el[9];nn=el[iel].eld[i].n;

     if(nn<2 || nn>rangv) continue;

     w=el[iel].eld[i].b;     wi.f=0; wi.Set(iel);

     if( XW(w,iel,0) )

      { if(GroupeObjetsChange(0,i) ) // action lignes

          {E$.E(gxw[rangv-2]);     E$.E(" digit ");

           E$.E(i+1); E$.E(" rows ");    E$.E(wf.String());

              E$.E( " columns ");      E$.Enl(wi.String(0));    

              return 1; }        }

    } // end iel

  }    // end i niv

return 0;}

 

 

 

 

.