SEclone  index conversion , bit fields and printing tags

 

Here some classes having a very general use

 

The corresponding files in the program are

#include "h\_00a_  I81.h"                // optimisation in index conversion

#include "h\_00b_  CB9ch.h"              // bitfield for digits

#include "h\_00c_  ZINFL.h"              // bitfield for cells

#include "h\_00d_  GG.h"                 // storing and handlin a grid 9x9 or 81

#include "h\_00e_  mms.h"                // do nothing normally to print a tag

 

 

The first class « I81 » has been designed to improve index conversion .

These functions replace some standard operations, trying to void expensive division.

 

Could be skipped, except that some optimization has already been done here or there.

 

// dummy class to have optimized functions for most common index correspondances

// pos(i,j) -> 9*i+j

// Mod3(i) -> i%3

// Div3(i) -> i+3

// Div9(i) -> i/9

// Boite(i,j) -> box index 0;9 for row i, column j

// PosBoite(i,j) -> box relative position 0;9 same row;column

 

class I81

{public:

 static inline USHORT Pos(int i,int j) {return ((i<<3)+i+j);}

 static inline USHORT Mod3(int i) {if(i<3) return i;  if(i<6) return i-3;  return i-6;}

 static inline USHORT Div3(int i) {if(i<3) return 0;  if(i<6) return 1;  return 2;}

 inline USHORT Div9(int i)

      {if(i<45){ if(i<9) return 0;  if(i<18) return 1;

                 if(i<27) return 2;if(i<36)return 3; return 4;}

       else  {if(i<54)return 5;if(i<63) return 6;if(i<72)return 7;return 8;}

       }

 inline USHORT Boite(int i,int j)

      {int jj=Div3(j); if(i<3) return jj; if(i<6) return (3+jj); else return (6+jj);}

 inline USHORT PosBoite(int i,int j) { return 3*Mod3(i)+Mod3(j);}

}i$;

 

Not that much to say; Only one member, but no data for it,

Most common conversion /3  /9  %3  are replaced by longer sequence that should be faster.

All these functions are “inline”.

 

Bit Fields

 

The program uses several bit fields. The most common are

 

CB9CH  a bit field length 16 mainly used to create some direct indexes for

              either candidates in a cell ….

              or  a direct index to  position or digit in a row/col/box

             

              but also for many other purposes as “common digits in a UR pattern”…

 

BIT32  is only provides in case a 32 field is needed

 

ZINFL is a 81 bits field whose main uses are

 

           describing cells under influence of a specific cell (20 cells in general)

           giving a quick view of  a rookery

           81 index for a row/col/box or any other object made of several cells

 

CB1024 a much bigger bit field key of the tagging process that will be described later.

 

As much as possible, the same rules apply to all these bit fields

 

Operators &;  |;  ^;  &= ; |= ; ^=  have been overloaded

Operator “-” is overloaded  a - b is the same as  a ^ (a&b)

 

Most overloaded operators have been made “inline”

Here after, the class CB9CH and the class BIT32  as an example

 

// bitfield giving valid digit in a specific place

// and basic functions linked to the bit field

class CB9CH

 {public:

 // static CB9CH v_0,v_1x;

  USHORT f;   // bitfield

  CB9CH() {f=0;}               // constructors

  CB9CH(int i1) {f=1<<i1;}

  CB9CH(int i1,int i2) {f=(1<<i1) | (1<<i2);}

  CB9CH(int i1,int i2,int i3) {f=(1<<i1) | (1<<i2) | (1<<i3);}

  CB9CH(int i1,int i2,int i3,int i4) {f=(1<<i1) | (1<<i2) | (1<<i3) | (1<<i4) ;}

  CB9CH(int i1,int i2,int i3,int i4,int i5)

         {f=(1<<i1) | (1<<i2) | (1<<i3) | (1<<i4) | (1<<i5);}

 

 

  inline int On(int ch)  {return ((f & (1<<ch))); }

  inline int Off(int ch)  {return (!(f & (1<<ch))); }

  inline void Set(USHORT ch) {f|=(1<<ch);}

  inline void Clear(USHORT ch) {f&=~(1<<ch) ;}

  inline void InitUn() {f=0x1ff;}

  inline CB9CH operator &(CB9CH & e){CB9CH w; w.f=f&e.f;  return w;}

  inline CB9CH operator |(CB9CH & e){CB9CH w; w.f=f|e.f;  return w;}

  inline CB9CH operator ^(CB9CH & e){CB9CH w; w.f=f^e.f;  return w;}

  inline CB9CH operator -(CB9CH & e) {CB9CH w; w.f=f^(e.f&f);  return w;}

  inline int  operator ==(CB9CH & e){return(e.f==f);}

  inline void operator &=(CB9CH & e){f&=e.f; }

  inline void operator |=(CB9CH & e){f|=e.f; }

  inline void operator ^=(CB9CH & e){f^=e.f; }

  inline void operator -=(CB9CH & e) {f^=(f&e.f); }

  inline USHORT GetOne() // valable pour un seul en mode très rapide pas de sécurité

  { if (f>16) {if(f>64) {if(f&128) return 8; else return 9;}

                        else if(f&64) return 7; else return 6;}

        else  if(f<4)return f;//1 ou 2

               else if(f&4) return 3; else if(f&8) return 4;else return 5;}

  int  First(){for( int i=0;i<9;i++) if(On(i)) return i; return 9;}

 

  USHORT QC (){USHORT n=0;for(int i=0 ;i<9;i++) if(On(i)) n++; return n;}

 

  int paire(){return (QC()==2);};     // QC est QuickCount

 

  USHORT CountEtString(char *s){USHORT n=0;for (int i=0 ;i<9;i++)

              if(On(i)) s[n++]=(char)(i+'1');   s[n]=0; return n;}

 

  char * String(int lettre=0){static char ws[10]; int n=0;

         for (int i=0 ;i<9;i++)  if(On(i)) ws[n++]=(char)(lettre?i+'A':i+'1');

         ws[n]=0;  return ws;}

  };

 

// CB9CH CB9CH::v_0,CB9CH::v_1x;

 

class BIT32

 {public:  UINT f;   // bitfield

  BIT32() {f=0;}               // constructor

  inline int On(int ch)  {return ((f & (1<<ch))); }

  inline int Off(int ch)  {return (!(f & (1<<ch))); }

  inline void Set(USHORT ch) {f|=(1<<ch);} 

  inline void Clear(USHORT ch) {f&=~(1<<ch) ;}

  inline void Inv(USHORT ch) {f^=(1<<ch) ;}

 

  inline BIT32 operator -(BIT32 & e) {BIT32 w; w.f=f^(e.f&f);  return w;}

};

 

When the size of 32 bits is passed, the process is slightly more complex.

Here the ZINFL class having 81 bits -> 3 integers 32 bits

// bitfield 81 positions (one per cell)

// and usual operations made on that field

 

class ZINFL

 {private:        static int io,jo;

    void ij(int v) {io=v>>5;jo=v&0x1F;};   //v/32  v%32

  publicunsigned  int f[3];   // bitfield

    ZINFL(){Init();}

    ZINFL(int i1){Init();Set(i1);}

    ZINFL(int i1, int i2){Init();Set(i1);Set(i2);}

 

    inline void InitUn(){f[0]=f[1]=-1;f[2]=0x1ffff;}

    inline void Init() {f[0]=f[1]=f[2]=0;}

 

    inline int On(int v) {ij(v);return (f[io]& (1<<jo));}

    inline int Off(int v) {ij(v);return (!(f[io]& (1<<jo)));}

    inline void Set(int v) {ij(v);f[io]|=1<<jo;}

    inline void Clear(int v) {ij(v);    f[io]&=~(1<<jo);}

 

    inline int NonNul(){ return (f[0]||f[1]||f[2]);}

    inline int Nul(){ return ((f[0]|f[1]|f[2])==0);}

 

 

    ZINFL operator |(ZINFL & b){ZINFL w; w.f[0]=f[0]|b.f[0];

                   w.f[1]=f[1]|b.f[1]; w.f[2]=f[2]|b.f[2];   return w; }

    void operator |=(ZINFL & b){f[0]|=b.f[0];f[1]|=b.f[1];f[2]|=b.f[2];}

 

    ZINFL operator &(ZINFL & b){ZINFL w; w.f[0]=f[0]&b.f[0];

                    w.f[1]=f[1]&b.f[1]; w.f[2]=f[2]&b.f[2];   return w; }

    void operator &=(ZINFL & b){f[0]&=b.f[0];f[1]&=b.f[1];f[2]&=b.f[2];}

 

    ZINFL operator ^(ZINFL & b){ZINFL w; w.f[0]=f[0]^b.f[0];

                            w.f[1]=f[1]^b.f[1]; w.f[2]=f[2]^b.f[2];   return w; }

    void operator ^=(ZINFL & b){f[0]^=b.f[0];f[1]^=b.f[1];f[2]^=b.f[2];}

 

    ZINFL operator -(ZINFL & b) {ZINFL w; for(int i=0;i<3;i++)

                                     w.f[i]=      f[i]^(f[i]&b.f[i]); return w; }

    void operator -=(ZINFL & b) {for(int i=0;i<3;i++)f[i]^=(f[i]&b.f[i]);  }

 

    ZINFL operator ~(){ZINFL w;  w.f[0]=~f[0];

                                    w.f[1]=~f[1]; w.f[2]=~f[2];   return w;  }

    int operator ==(ZINFL & b){ return ((f[0]==b.f[0])

                                      &&(f[1]==b.f[1])&&(f[2]==b.f[2])); }

    int EstDans(ZINFL & fe)       {return (((*this)&fe )==(*this));}

 

    ZINFL Inverse()    {ZINFL w;  w.f[0]=f[0]^(-1);w.f[1]=f[1]^(-1);

                                           w.f[2]=f[2]^0x1ffff;   return w;  }

 

    int NextI(int i){ if(On(i)){Clear(i); return 1;}return 0;}

    void Clear(ZINFL & z) {for (int i=0;i<3;i++)  f[i]^=(f[i]&z.f[i]); }

    int Next() {for(int i=0;i<81;i++) if(NextI(i)) return i;return 128;}   

    int First(){for(int i=0;i<81;i++) if(On(i)) return i;return 128;}    

 

 

    int Count(){int n=0;for(int i=0 ;i<81;i++) if(On(i)) n++; return n;}

    void Imageligne(char * lib);

    void Candidats(char * lib,char ch); 

    void ImagePoints(); 

  };

 

int ZINFL::io=0, ZINFL::jo=0;

 

Some of these functions should be obsolete, as Candidats() and likely ImageLigne()

 

Printing a tag

 

Although this is for chains, I show now  that simple class.

Tags are internal integers with even and odd  successive values dedicated to strong links, forming layers.

 

Printing is made using for each pair of tags “upper case” lower case” letters.

 

That class makes the switch (initialized by the constructor)

 

// class to print a tag

// normally not used here but kept to save time in cleaning the code

//   and for ptinying of the path whrn tzgging is in use

 

class MMS

 

 {public:   MMS()  // creation des vecteurs

          { n=0; int i;   for(i=0;i<26;i++) charge('a'+i,'A'+i);

                          for(i=192;i<223;i++) charge(i,i+32);

            charge(159,255); charge(138,154);

             ma[n]=mb[n]=0; }

 

  char val(int mm)    {int im=mm>>1; if((im>=n)||(im<1)) return (char)164;

                                   if(mm&1) return mb[im-1];else return ma[im-1];};

 

  inline void ev(int mm)     {E$.E(val1(mm));}

  inline void evnl(int mm)   {E$.Enl(val1(mm));}

 

  private :

  char ma[100],mb[100];    int n;

  char* val1(int me)

          {static char ss[]="  " ,

        cl[]="£$€§&@?!0123456789%µ*~+:<>²²²²²²²²²²²²²²²²²²°°°°°°°°°°°°°°°°°°°°°";

        int mm=me>>1,nm;

        if(mm<n) {ss[1]=0; ss[0]=val(me); return ss;}

         mm=mm-n;   nm=mm/26; mm=((me-2*n)%52)+2;

         ss[0]=cl[nm]; ss[1]=val(mm); return ss;}         

        

  void charge(int ia,int ib)       { ma[n]=(char)ia;mb[n++]=(char)ib;};

  }mms;