SEclone basic classes for tagging

The table of candidates TZPTLN continued

 

Tpt2.cpp

    has only, for the time being the search of eliminations thru a loop within a layer

 

// specifically prepared for SE clone

 

// look for xcycle with single digit single candidates tagged

// count tag per row/col/box and look for extra candidates

 

 

 

int TZPTLN::Xcycle() // look for xcycle made of strong links

{E$.Enl("\nzptln Xcycle ");

 int ir=0; for(int i=2;i<mfinc;i+=2) ir+=XcycleTag(i); return ir;}

 

 

int TZPTLN::XcycleTag(int tag)

{USHORT ch=zp[tag_to_point[tag]].ch;

 USHORT tc1[27],tc2[27],tc3[27]; ZINFL zw; int ir=0;

 for(int i=0;i<27;i++) tc1[i]=tc2[i]=tc3[i]=0;

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

       {int i8=zp[i].ig; if(i8>=81) continue;// should never be

     P81F f=t81f[i8];

     if(zp[i].m==tag) {tc1[f.el]++; tc1[f.pl+9]++;tc1[f.eb+18]++;zw.Set(i8);}

     else if(zp[i].m==(tag^1))

                {tc2[f.el]++; tc2[f.pl+9]++;tc2[f.eb+18]++;zw.Set(i8);}

     else if(zp[i].ch==ch){tc3[f.el]++; tc3[f.pl+9]++;tc3[f.eb+18]++;}

    }

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

  {if(tc1[el]==1 && tc2[el]==1 && tc3[el]>0)// we got one loop

   {if(o$.ot){ E$.E(" xcycle one tag el="); E$.E(el+1);E$.E(" tag=");

               mms.ev(tag);E$.Enl();}

       CB1024 cbd,cbf; USHORT p1,p2;

         for(int i=1;i<ip;i++) // we enter the chain in the  the length

        {int i8=zp[i].ig;  P81F f=t81f[i8];

         if (f.el==el ||(f.pl+9)==el || (f.eb+18)==el)

                      if(zp[i].m==tag) {cbd.Set(i);p1=i;}

                      else if(zp[i].m==(tag^1)){cbf.Set(i);p2=i;}

         }

   jdk.PointK();// increase the milestone

   int length=zl.Chemin(cbd,cbf,0);// if ok build the chain

   if(!length) {E$.E(" xcycle sans chemin ");

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

                            continue;}  // should not be

   if(o$.ot){E$.E(" xcycle  ");

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

   if(!tchain.Chaine(length+1,tag)) continue; // rating to high

   // now add eliminations to the last chain

   for(int i=1;i<ip;i++) // look again to catch points in that row/col/box

        {int i8=zp[i].ig; 

         if(zp[i].m==tag || zp[i].m==(tag^1)|| (zp[i].ch-ch)) continue;

         P81F f=t81f[i8];

         if (f.el==el ||(f.pl+9)==el || (f.eb+18)==el)

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

         }

     E$.E(" xcycle elims ");tchain.PrintElims();

    } 

  }// end el

return ir;}

 

 

 

Computing the length in SE mode (file tpt_length.cpp)

 

This is a relatively complex function.

We start from a  path defined I tag mode. Often, the start candidate is known (when a set is used or when a candidate does not belong to a layer of more than one strong link) but not always.

The process has been designed based on the fact that in most cases, we have in the path some weak links in tag form with only on corresponding weak link in “candidate form’.

 

We go from left to right, step by step and we build intermediate tables giving the shortest path form any start point to any end point. If we find in that process a “single weak link”, we have only one end candidate and if we have a known start candidate, we have only oen final path for the step;

 

A block of 50 paths is used for other situations.

Note: that process is not a critical one. We have already filtered chains of interest.

 

Entry is Find_Length(); a separate process is done at the start and at the end. All intermediate steps follow a kind of recursive n-1 -> n process

 

 

 

/* we have found a valid chain or loop in tags terms

   switch to the shortest path (AIC) in candidates terms

   path is the path found in tags terms

   start, if not 0, it the start point (used for sets)

   We have to try all weak links and all bridges between weak links

 */

 

int TZPTLN::Find_Length(PATH & path,USHORT start)

{// can stop if have pass the tchain limit

 // initial is the list of weak links for the start

 // to connect to the start point if forced

Find_First(path.GetFirst(),path.Get(1)^1,start);

 

            // then go to the end

for (int i=1;i<path.ipth-1;i++) LengthStep(path.Get(i),path.Get(i+1)^1);

             // if necessary do end point == start point in all paths

 

length=100;pathr.ipth=0; 

if(!pathb1.nps) {length=0;return 0;}

 

for(int i=0; i<pathb1.nps;i++)

   {Find_Last(path,pathb1.ps[i]);

    if(pathb1.ps[i].ipth < length){pathr=pathb1.ps[i];length=pathr.ipth; }}

if(length>50) length=0;

//else {E$.E("length final length=");E$.E(length);pathr.PrintPath();E$.Enl();}

return length-1;}

       // last step

 

 

void TZPTLN::Find_Last(PATH & pthm,PATH & pthw)

{USHORT ma=pthm.GetFirst(),mb=pthm.GetLast(),pa=pthw.GetFirst(),pb=pthw.GetLast();

 if((ma-mb) && (ma - (mb^1)) )return;

 if(pa==pb )return; // if not, fill the gap

 zl.Direct(pb,pa); if(!zl.length) return;

 pthw.Expand(zl.path1);

}

 

void TZPTLN::Find_First(USHORT m1,USHORT m2,USHORT start)

{pathb1.Init(); 

 for(int i=1;i<ip;i++) if(zp[i].m==m2)  Find_FirstD( m1,i,start);}

 

void TZPTLN::Find_FirstD(USHORT m1,int i,USHORT start) // take the shortest if start

{ZPTLN p1=zp[i]; USHORT g1=p1.ig; ZINFL z1= zgs.z[g1];

     USHORT ti[20],iti=0;

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

       {if(zp[j].m-m1) continue;

               ZPTLN p2=zp[j];  USHORT g2=p2.ig; 

           if(( g1==g2) ) {ti[iti++]=j;continue;}

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

           if(t81f[g1].ObjCommun(& t81f[g2]))  ti[iti++]=j;

     } // end for j

       if(!iti) return;

         // ========if start take the shortest

         // if not keep them all

    PATH phx;

       USHORT p0=0,lgth=100 ;

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

         {if(!start) {phx.Init(); phx.Add(ti[k]); phx.Add(i);

                      pathb1.Add(phx); continue;}

          if(start==ti[k]){phx.Init(); phx.Add(start); phx.Add(i);

                           pathb1.Add(phx); return;}

          zl.Direct(start,ti[k]);

          if(!zl.length) continue; // should never happen

          USHORT lgw=  zl.length  ; // first point already there but last missing

          if(lgw< lgth) {lgth=lgw;   phx=(zl.path1);

                          phx.Add(i);}// last point added

         } //end for k

   

   if(start && lgth<50) pathb1.Add(phx);  

}

 

 

/* a typical step in the search for the shortest path

  we have a list of shortest path for the previous step "start -  a"

  and we process a new step "a = A - b"

  so we first collect all weak links "A - b"

  then look for all "start" to all "b" keeping the new shortest

  we end with a collection of "start - b"

*/

void TZPTLN::LengthStep(USHORT m1,USHORT m2)

{pathb2.Init();

for(int i=1;i<ip;i++) if(zp[i].m==m2)  LengthStepD(m1,i);

pathb1=pathb2;

//pathb1.Image("fin cycle");

}

 

 

void TZPTLN::LengthStepD(USHORT m1,int i)

{ZPTLN p1=zp[i]; USHORT g1=p1.ig; ZINFL z1= zgs.z[g1];

     USHORT ti[20],iti=0;

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

       {if(zp[j].m-m1) continue;

               ZPTLN p2=zp[j];  USHORT g2=p2.ig; 

           if(( g1==g2) ) {ti[iti++]=j;continue;}

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

           if(t81f[g1].ObjCommun(& t81f[g2]))  ti[iti++]=j;

     } // end for j

 

        if(!iti) return;

      

         // ========now look for min length for each start point

    PATH phx,phw;

       USHORT p0=0,lgth=100 ;

    for(int ib=0;ib<pathb1.nps;ib++) // look for all

     {phw=pathb1.ps[ib];

         USHORT lg0=phw.ipth,

                      px=phw.GetFirst(),   // start point

                   py=phw.GetLast();  // end point

         if(px-p0) {if(lgth<50) pathb2.Add(phx);

                    p0=px; lgth=100;}

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

         {if(zl.IsDirect(py,ti[k]))  // most often

                 {if((lg0+2)< lgth) {lgth=lg0+2;   phx=pathb1.ps[ib]; phx.Add(ti[k]);

                          phx.Add(i);}// last point added

                  continue;}

               

          zl.Direct(py,ti[k]);

 

          if(!zl.length) continue; // should never happen

          USHORT lgw=  zl.length  +  lg0; // first point already there but last missing

          if(lgw< lgth) {lgth=lgw;   phx=pathb1.ps[ib]; phx.Expand(zl.path1);

                          phx.Add(i);}// last point added

         } //end for k

     }// end for ib

   if(lgth<50) pathb2.Add(phx);  

}