SEclone† URs ULs


The process for ULs and URs has been deeply transformed compared to my solver code.


Regarding URs, my solver considers many more patterns based on dual values, but had nothing on hidden sets.


For URs, I had a search process derived from tagging and I switched to a direct search.


I did not ry to decipher the code of Sudoku Explainer but I built partly out of example, partly out of discussion in the thread dedicated to that task, a kind of comprehensive process.


As I had difficulties to find the underlying logic, I worked more on patterns, assuming the same process apply to URís and ULís.


This created more code, but gives less room for bugs difficult to fix.


All the search should be done using the copy of the cells table to avoid interaction between several URís.


All URís ULís having the same rating are treated in the same step.


Iíll make a last quick check that that rule has been applied before delivering the code.


As the process can not be done in one to comply with SE rules, all URís, ULs† seen at the first step are stored in appropriate tables. Next steps restart from these tables.


Class CRIN to process to URís ULís and class CRINT storing URs


A specific class CRIN, one member is dedicated to UR processing and to most of the UL process.

In the same file#include "h\_05a_† RIN.h"we find the table to store URís to be processed later.

Most of the basic coed comes from my solver. May eb some more cleaning should be done.


// class defined to handle Unique rectangles and Unique loops

// the search for URs is started in TP81, locating potential URs

// That class is called by TP81


class CRIN† {public:†††† //on ne traite que deux communs.

static P81 *ta,*tr; // ta action, tr recherche

static OBBIEL * tchel;

CB9CH wc,wou,wr;††

int† ia,ib,ic,id,deux[4],plus[9],pp1,pp2, // voir pourquoi plus est 9

†††† ndeux,nplus,nwc,ch1,ch2,chc1,chc2,nautres,diag,rating;


// data specific to common processing UR/UL (need sub routines)

int th[10],td[10],tnh[10],nth,ntd,nnh,aig_hid;

CB9CH wh,wd,wnh,wnd,wdp;

ZINFL zwel; // to prepare clearing of naked sets



CRIN(){ta=T81t;tr=T81tc;tchel=aztob.tchbit.el;}†† // constructor


††† // short functions called by the mains ones


int GetElPlus() {return tp81f.GetLigCol(pp1,pp2);}// assuming nplus=2

int IsDiag()††† {if(divf.IsObjet(deux[0],deux[1])) diag=0;

†††††††††††††††††††††† else diag=1; return diag;}

int Setw(){wc=tr[ia].v.cand & tr[ib].v.cand & tr[ic].v.cand & tr[id].v.cand;††

††††††††††† nwc=wc.QC();† return nwc; }

int Setwou(){wou=tr[ia].v.cand | tr[ib].v.cand | tr[ic].v.cand | tr[id].v.cand;

†††††††††††† wr=wou^wc;††††† nautres=wr.QC();††††† return nautres; }


void CalDeuxd(int i) {if((tr[i].v.cand-wc).f) plus[nplus++]=i; else deux[ndeux++]=i;}

void CalcDeux()†† {ndeux=nplus=0;

†††††††††††††††††† CalDeuxd(ia);CalDeuxd(ib);CalDeuxd(ic);CalDeuxd(id);

†††††††††††††††††† pp1=plus[0];pp2=plus[1];}


inline int Jum(USHORT el,USHORT ch) {if (tchel[el].eld[ch].n==2)return 1;return 0;}

int Jumeau(USHORT a,USHORT b,USHORT ch){USHORT el=tp81f.GetLigCol(a,b); return Jum(el,ch);}


int GetJJDir(USHORT a,USHORT b,USHORT c,USHORT d,int ch)

†††††††††††††††††† { int ok=Jumeau(a,b,ch); ok+=Jumeau(b,d,ch)<<1;

†††††††††††††††††††† ok+=Jumeau(c,d,ch)<<2;ok+=Jumeau(a,c,ch)<<3; return ok;}

int GetJJDir(int ch){ int ok=Jumeau(ia,ib,ch); ok+=Jumeau(ib,id,ch)<<1;

††††††††††††††††††††† ok+=Jumeau(ic,id,ch)<<2;ok+=Jumeau(ia,ic,ch)<<3; return ok;}


void GenCh(){CB9CH ww=wr;ch1=ww.First(); ww.Clear(ch1);ch2=ww.First();

†††††††††††† ww=wc;chc1=ww.First(); ww.Clear(chc1);chc2=ww.First();}


ZINFL GetZ(){ZINFL zw(ia,ib);zw.Set(ic);zw.Set(id);return zw;} // le zinfl des 4 points



void ImageRI(char * lib,USHORT a)

††††††††† { E$.E( lib);E$.E(tr[a].f->pt);E$.E(" ");E$.E( tr[a].scand);}

void ImageRI(char * lib)

††††††††† { if(!o$.ot) return;

†††††† ††††††† E$.E( "->UR" );E$.E( lib);ImageRI(" P1=",ia) ;ImageRI(" P2=",ib) ;

††††††††††† ImageRI(" P3=",ic) ;ImageRI(" P4=",id) ;E$.Enl();}



†††††† // look for pseudo locked set in a unique loop

int† StartECbi(USHORT p1,USHORT p2,CB9CH com, int action)

††††††††† {pp1=p1;pp2=p2; wc=com;

†††††††††† chc1=com.First();com.Clear(chc1);chc2=com.First();

††††††††††† wr=(ta[p1].v.cand | ta[p2].v.cand)-wc; nautres=wr.QC();

††††††††††† return T2(action);}†


†† int T2(USHORT action);

†† int T2_el(USHORT el,USHORT action);

†† int T2_el_set(USHORT len);// if len =0 get len if len>0 go

†† int T2_el_set_nacked(USHORT len);

†† int T2_el_set_hidden(USHORT len);

†† int T2_el_set_nack_pair();


// main subroutines



†† int RID(int l1,int l2,int c1,int c2);† // entry : a potential UR to check

†† int RID2(int rat);

††† }y$;



P81 * CRIN::ta,*CRIN::tr; // ta action, tr recherche

OBBIEL * CRIN::tchel;




// CRINT is a table storing possible UR type other than 1 for further processing

class CRINT†


CRIN tur[20];†

int n;

void Init() {n=0;}

void Store(CRIN *x) {if(n<20) tur[n++]=(*x);}

int Traite(int rat)

†††††† {int irat=rat-44; if(irat<2 || irat>4) return 0;

††† // E$.E("recherche UR rating =");E$.E(rat);E$.E(" pour irat=");E$.Enl(irat);

†††††† †for(int i=0;i<n;i++) ††††† †††††† †††††† †if( tur[i].T2(irat)==1)

†††††† ††††† {tur[i].ImageRI(" action from object");†††† return 1; }††††

†††††† †return 0;}



Some comments on that file.


In the constructor, tr is set to the copy of the table of cells. All the search should be done using tr.

action, reversely is done out of the main table of cells.


tchel is not updated during a cycle, so there is no need for a copy.


As nearly nothing is done thru bi values, I guess some routines are obsolete;