SEclone basic classes for tagging

The table of candidates TZPTLN continued

 

I’ll comment only the main entries and data in that class (omitting what can be obsolete)

 

  USHORT ip,ipbase,

         tag_to_point[800],  // direct link set when tagging

         tag_count[800],     // number of points per tag

       mfinc,ptsch[100],iptsch;

  USHORT mch[20],ich,el,nmch;       // pour gen chx

  ZINFL zf[10],zptsch[100],zel;

 

 

tag_to_point  is a direct index to the last candidate found with that tag

tag_count is the number of candidates for that tag  (both set in MarqueSolde())

mfinc is the value for the next tag at the end of the main tagging process.

          It is also the first tag passing the layers       

 

  void  InitCol() {for (int i=0;i<ip;i++)zp[i].m=0;

                   for(int i=0;i<600;i++) tag_to_point[i]=0;}// not tagged

 

                     //==============TPT0

  void MarquerSolde() ;

  void Conflits(){}// obsolete

  void ConflitsCase();  

  void ConflitsChiffres(){for(USHORT ich=0;ich<9;ich++) ConflitsChiffre(ich); }

  void ConflitsChiffre(USHORT ch);  

  void ConflitsD(USHORT ix);

  void GenereZcx();     

 

 

This set of routine in part of the central process

InitCol is called before tagging in each step of the search of chains

MarquerSolde is the last step in tagging

         associates a tag to non tagged candidates

        creates the tables  tag_to_point and tag_count

Conflits… generate the basic weak links « candidate _ candidate » (in tag form)

Generezcx generates sets of tags made of candidates of the same row/column/box.

       (could keep a direct access to them to speed up the process later)

 

 

                 //========= TPT1 work within a layer

  void Impossible(int base);

  void Impossible_loop(USHORT p1,USHORT p2);

  int Chain_layer(USHORT ptd,USHORT ptf);

  void SuppMarque(USHORT mm,int direct=0);  

 

 

This set of routine comes after tagging and finds what can be done within layers.

No weak link is needed if any contradiction appears (Impossible())

Weak links are used to locate the eliminations  in other cases;

 

Other functions will be discussed later;

 

.

Now the routines included in tpt0.cpp

 

MarquerSolde() is part of the tagging process. It is call after all strong links have been tagged.

           That function prepare further processing,

                      identifying for example FALSE tags, which will only be used for nested chains

                      Setting tag to point as a direct index

           The last action is to set the CB1024 size to what is necessary.

Conflit…  are functions generating the basic weak links 

Generezcx generate the sets of tags for a cell or a row/colum/box.

           Here, as we have only single candidates, the process is relatively simple,

          one set and only one (at max)  for each digit;row  digit;column ..

 

Other functions will be discussed lat

 

  /* tag untagged points        prepare the direct iindex tag_to point

     set up the list of good/false tags in use here */

 

  void TZPTLN::MarquerSolde() // en mode boucle interdite

 {CB1024 zw;zw.Init(); mfausses=mbonnes=zw; ntag_ok=0;mfinc=col;

   for (int i=1;i<ip;i++)

  {USHORT tag=zp[i].m;

   if(!zp[i].m )   {zp[i].m = col;tag=col; col+=2;}

   tag_to_point[tag]=i; // direct index

   tag_count[tag]++;

   if(!zw.Isch(tag)) // is it the first time the tag is seen

    {zw.Set(tag);// yes mark it

        ZINFL zz=zgs.z[zp[i].ig]&jdk.csol[zp[i].ch];// is it a good candidate

        if(zz.Nul())mfausses.Set(tag);

        else

         {mbonnes.Set(tag);     tag_ok[ntag_ok++]=tag;}

    }

 }

 CB1024::SetIsize((ip>col)?ip:col); 

 }// setisize mini  ip to use it as a zpln bitfield

 

void  TZPTLN::ConflitsCase()

{int jp; // conflits case

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

  {iptsch=0; jp=i;  if(T81t[i].v.cand.f<2) continue;

   for(int ich=0;ich<9;ich++,jp+=81)

    {int j=iptl.ic[jp];if(!j) continue;      if(!zp[j].m)continue;

     ptsch[iptsch++]=j;   }

   if(iptsch)ConflitsD();

 }

 }

void  TZPTLN::ConflitsChiffre(USHORT ich)

{for (el=0;el<27;el++)

   {   iptsch=0;  if(aztob.tchbit.el[el].eld[ich].n <2 )continue;

    zel=divf.elz81[el]&jdk.c[ich];

    for(int j=0;j<ip;j++)

     {if((zp[j].ch-ich )|| (!zp[j].m))continue;

      ZINFL zw=zgs.z[zp[j].ig],zw1=zw&zel;

      if(zw==zw1)

       {zptsch[iptsch]=zw;ptsch[iptsch++]=j;}}

    if(iptsch)ConflitsD();

    }

}

void  TZPTLN::ConflitsD()

{for(int j=0;j<iptsch-1;j++)// départs pour couples

     {USHORT p1=ptsch[j],m1=zp[p1].m;

      for(int k=j+1;k<iptsch;k++)

       { USHORT p2=ptsch[k],m2=zp[p2].m;

         if(m1==m2)continue;             if(m1==(m2^1)) continue;

        zcf.Chargeid(m1,m2,0,p1,p2)    ;

       }  }}

 

//---------- gen sets of candidates in a row column box

void TZPTLN::GenereZcx()     // can only be one per row col box, only if more than 2 candidates

{ for( ich=0;ich<9;ich++) for (el=0;el<27;el++)

   {USHORT nmch=aztob.tchbit.el[el].eld[ich].n,ipts=0;;

       if(nmch<3) continue; // minimum set size is 3

       iptsch=0;  zel=divf.elz81[el]&jdk.c[ich];  int j;

    for(j=0;j<ip;j++)

     {if(zp[j].ch-ich )continue;

      if(zel.On(zp[j].ig) )

                {mch[ipts+nmch]=j;mch[ipts++]=zp[j].m;     }

     }

     zcx.Charge(mch,nmch,1,ich);

    }

}

 

 

Now the routines included in tpt1.cpp

 

Impossible() looks for and process all conflicts within a layer.

           The action depends on the step in the process

           With rating 6.5 we have only to look for Xloop or Yloop

           With rating >6.5 we look for chains with one specificity

               we can find a hidden kite based on the conflict

SuppMarque() is the general entry to eliminate a tag.

         Unless direct action is required, that function loads eliminations  in TCHAIN

 

 

/* within a layer, locate if any the same tag

   either in on cell

   or in one row/column/box with the same digit*/

 

void TZPTLN::Impossible(int base)

{//se_refus << "impossible " << base <<" " << tchain.rating<<endl;

 for(int j=0;j<ip-1;j++)

    {ZPTLN p1=zp[j]; int m1=p1.m,g1=p1.ig;  

     if(m1>=mfinc) continue;

     ZINFL z1= zgs.z[g1];

     for(int k=j+1;k<ip;k++)

       {ZPTLN p2=zp[k];  int m2=p2.m,g2=p2.ig;    if(m2-m1) continue;

       

           if( g1==g2 )

              {// should always be base>65

                            E$.E("->conflit case  "); p1.Image();p2.Image();   E$.Enl();

                     if(Chain_layer(j,k)) SuppMarque(p1.m);  }

         else

                       {if (p1.ch-p2.ch) continue;

                     if(!t81f[g1].ObjCommun(& t81f[g2])) continue;

                          if(base>65) // then look for a chain

                 {if(o$.ot)

                                    {jdk.PointK();E$.E("->conflit objet ");

                                p1.Image();p2.Image(); E$.Enl();}

                       if(zl.HiddenKite(g1,g2,p1.ch)) continue;                           

                            if(Chain_layer(j,k))SuppMarque(p1.m);}

                else // more complex, look for a cycle could be rating 65

                               // the candidate outside the loop can be any of the 2

                            {// but first try a hidden kite

                                                  

                             Impossible_loop(j,k);Impossible_loop(k,j);         }

                 }

       }} // end for k  j

 //se_refus << "impossible fin" << base <<" " << tchain.rating<<endl;

 

}

 

/*===== find a loop with p2 external to the loop

  start point can be any candidate in zl.tdir[p2]

  but also a possible hidden kite must be considered

  */

 

 

 void TZPTLN::Impossible_loop(USHORT p1,USHORT p2)

 {if(o$.ot){jdk.PointK();E$.E("->conflit to solve thru loop ");

                     zp[p1].Image();zp[p2].Image(); E$.Enl();}   

 

  USHORT *ti=zl.tdir[p2].ti,iti=zl.tdir[p2].iti,length=200;

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

   {E$.E("->try thru loop ");

                     zp[p1].Image();zp[ti[i]].Image();  zp[p2].Image(); E$.Enl();     

        int lengthw=zl.Loop_thru(p1,ti[i],p2);

    if(lengthw && lengthw<=length)

              {length=lengthw;

            jdk.PointK();

            if(!tchain.Chaine(length,zl.path1.GetFirst())) continue;

               zl.Clean(1);}

   }

 

 }

 

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

 int  TZPTLN:: Chain_layer(USHORT ptd,USHORT ptf)

 {if(o$.ot)

 {E$.E("chain layer "); zp[ptd].Image();  E$.E(" -> "); zp[ptf].Image();  E$.Enl();}

  jdk.PointK();// increase the milestone

  int length=zl.Chemin(ptd,ptf);// if ok build the chain

  if(length<1) return 0;

  zl.path1.PrintPath();//PrintPath(zl.mch,zl.ichbon);

  return tchain.Chaine(length,zp[ptd].m) ;

 }

 

//  just add eliminations in the last chain

 // except if Direct is true

void TZPTLN::SuppMarque(USHORT m,int direct)

{for (int i=1;i<ip;i++) if(zp[i].m==m)

      if(direct)T81t[zp[i].ig].Change(zp[i].ch);

         else   tchain.AddLast(zp[i].ig,zp[i].ch);

}