Beispiel #1
0
        public Bit981(UGLink UGL) : this()
        {
            Bit981 B = new Bit981();

            if (UGL.rcBit81 is Bit81)
            {
                int no = UGL.rcBit81.no;
                B._BQ[no] = UGL.rcBit81;
                foreach (int rc in UGL.rcBit81.IEGet_rc())
                {
                    B._BQ[no].BPSet(rc);
                }
                if (!UGL.rcBit81.IsZero())
                {
                    nzBit |= (1 << no);
                }
            }
            else
            {
                UCell uc = UGL.UC as UCell;
                foreach (var n in uc.FreeB.IEGet_BtoNo())
                {
                    B._BQ[n].BPSet(uc.rc);
                    nzBit |= (1 << n);
                }
            }
        }
Beispiel #2
0
 public Bit981(Bit981 Q) : this()
 {
     this.nzBit = Q.nzBit;
     for (int n = 0; n < sz; n++)
     {
         this._BQ[n] = Q._BQ[n];
     }
 }
Beispiel #3
0
 public uint CompareTo(Bit981 B)
 {
     for (int n = 0; n < sz - 1; n++)
     {
         if (this._BQ[n] == B._BQ[n])
         {
             return((uint)(this._BQ[n].CompareTo(B._BQ[n])));
         }
     }
     return((uint)(this._BQ[sz - 1].CompareTo(B._BQ[sz - 1])));
 }
Beispiel #4
0
        static public Bit981 operator-(Bit981 A, Bit981 B)
        {
            Bit981 C = new Bit981();

            for (int n = 0; n < sz; n++)
            {
                C._BQ[n] = A._BQ[n] - B._BQ[n];
            }
            __Set_nzBit(C);
            return(C);
        }
Beispiel #5
0
        public Bit981 Copy()
        {
            Bit981 Scpy = new Bit981();

            for (int n = 0; n < sz; n++)
            {
                Scpy._BQ[n] = _BQ[n].Copy();
            }
            Scpy.nzBit = this.nzBit;
            return(Scpy);
        }
Beispiel #6
0
        public override bool Equals(object obj)
        {
            Bit981 A = obj as Bit981;

            if (A == null)
            {
                return(false);
            }
            for (int k = 0; k < sz; k++)
            {
                if (_BQ[k] != A._BQ[k])
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #7
0
        static private void __Set_nzBit(Bit981 C)
        {
            int nzBit = 0;

            for (int n = 0; n < sz; n++)
            {
                if (C._BQ[n].IsZero())
                {
                    nzBit &= ((1 << n) ^ 0x7FFFFFFF);
                }
                else
                {
                    nzBit |= (1 << n);
                }
            }
            C.nzBit = nzBit;
        }
        public UGLink(UCell UC)
        {
            this.SrNum = SrNum0++; this.UC = UC;
            rcbn2      = new Bit981();
            rcbn_conn2 = new Bit981();
            foreach (var n in UC.FreeB.IEGet_BtoNo())
            {
                rcbn2.BPSet(n, UC.rc);
            }
            for (int n = 0; n < 9; n++)
            {
                rcbn_conn2._BQ[n] |= p_connectedCells[UC.rc];
            }

            int _rcbFrame = (1 << UC.r | 1 << (UC.c + 9) | 1 << (UC.b + 18));

            rcbnFrame2 = (long)_rcbFrame | ((long)UC.FreeB) << 27;                   //■
        }
 public bool Check_connected(Bit981 HB981)
 {
     if (rcBit81 is Bit81)
     {
         int no = rcBit81.no;
         return(HB981._BQ[no].IsHit(rcbn_conn2._BQ[no]));
     }
     else
     {
         int rc = UC.rc;
         foreach (var n in UC.FreeB.IEGet_BtoNo())
         {
             if (HB981._BQ[n].IsHit(rc))
             {
                 return(true);
             }
         }
         return(false);
     }
 }
        public UGLink(Bit81 rcBit81)
        {
            this.SrNum   = SrNum0++;
            this.rcBit81 = rcBit81; this.sz = rcBit81.BitCount();
            rcbn2        = new Bit981(rcBit81);

            rcbn_conn2 = new Bit981();
            var _conn = new Bit81();

            foreach (var rc in rcBit81.IEGet_rc())
            {
                _conn |= p_connectedCells[rc];
                for (int n = 0; n < 9; n++)
                {
                    rcbn_conn2.BPSet(n, rc);
                }
            }
            int no = rcBit81.no;

            rcbn_conn2._BQ[no] = _conn - rcBit81;
            rcbnFrame2         = (long)rcBit81.Get_RowColumnBlock() | ((long)1 << (no + 27)); //■
        }
        public IEnumerable <UBasCov> IEGet_BaseSet(int sz, int rnk)
        {
            if (UGLLst == null)
            {
                yield break;
            }

            __checkCC = 0;

            List <UGLink> basUGLs   = new List <UGLink>();
            Bit981        HB981     = new Bit981();     //BaseSet bitPattern
            Bit324        usedLK    = new Bit324();     //usedLink(by serial number)
            List <int>    usedLKLst = new List <int>();

            Bit81Chk coverChk = new Bit81Chk(sz, rnk, basUGLs, usedLKLst, usedLKIgnrLst);

            var  cmbBas = new Combination(UGLLst.Count, sz);
            long rcbn36 = 0;

            int jkC = 0;
            int nxt = int.MaxValue;   //(skip function)

            while (cmbBas.Successor(nxt))
            {
                GeneralLogicGen.ChkBas1++;                       //*****

                jkC++;
                //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* sz=1
                if (sz == 1)
                {
                    UGLink UGL = UGLLst[cmbBas.Index[0]];
                    if (UGL.UC is UCell)
                    {
                        goto LNextSet;                   // if size=1, cell-type is invalid
                    }
                    // UGL.rcBit81 is Bit81
                    int blkB = (int)UGL.Get_rcbnFrame(2);
                    if (blkB.BitCount() > 1)
                    {
                        goto LNextSet;
                    }

                    int no = UGL.rcBit81.no, b = blkB.BitToNum();
                    var P = UGLLst.Find(U => U.Equal_no_block(no, b));
                    if (P == null)
                    {
                        goto LNextSet;
                    }
                    if ((P.rcBit81 - UGL.rcBit81).Count == 0)
                    {
                        goto LNextSet;
                    }

                    //there are numbers only within one block
                    HB981.Clear();    HB981.BPSet(UGL.rcBit81.no, UGL.rcBit81, tfbSet: false);
                    basUGLs.Clear();  basUGLs.Add(UGL);
                    GeneralLogicGen.ChkBas2++; //*****
                    goto LBSFound;             //possibility of solution
                }

                //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* sz>=2
                HB981.Clear();
                basUGLs.Clear();
                usedLKLst.Clear();
                coverChk.Clear();
                rcbn36 = 0;

                //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2

                for (int k = 0; k < sz; k++)
                {
                    nxt = k;
                    UGLink UGL = UGLLst[cmbBas.Index[k]];
                    rcbn36 |= UGL.rcbnFrame2;

                    if (!Check_rcbnCondition(sz, rnk, k, rcbn36))
                    {
                        goto LNextSet;            //# Extremely efficient
                    }
                    if (UGL.rcBit81 is Bit81)     // ............ rcb ............
                    {
                        if (k > 0 && HB981.IsHit(UGL.rcBit81.no, UGL.rcBit81))
                        {
                            goto LNextSet;                                      //included in BaseSet
                        }
                        HB981.BPSet(UGL.rcBit81.no, UGL.rcBit81, tfbSet: true); //register to BaseSet
                        usedLKLst.Add(UGL.rcBit81.ID);                          //tfx<<4 | no
                        int no = UGL.rcBit81.no;
                        coverChk.noB |= 1 << no;                                //qq
                    }
                    else                                                        // ........... Cell ............
                    {
                        UCell UC = UGL.UC;
                        int   rc = UC.rc;
                        foreach (var n in UC.FreeB.IEGet_BtoNo(9))
                        {
                            if (k > 0 && HB981.IsHit(n, rc))
                            {
                                goto LNextSet;
                            }
                            HB981.BPSet(n, rc, tfbSet: true);
                        }
                        int IDrc = rc << 17 | 1 << 16;
                        usedLKLst.Add(IDrc);                         //tfx<<4 | no
                    }
                    basUGLs.Add(UGL);                                //qq
                }
                GeneralLogicGen.ChkBas2++;                           //*****

                bool niceB = coverChk.Check_BaseSetCondition(HB981); //########## check_rcB9 ##########
                if (!niceB)
                {
                    goto LNextSet;
                }

                //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2
                if (sz >= 2)
                {
                    int noBP = HB981.nzBit;
                    int noCC = noBP.BitCount();
                    if (noCC >= 2)
                    {
                        List <int> IX = noBP.IEGet_BtoNo().ToList();

                        if (sz >= 2)
                        {
                            for (int k = 0; k < noCC; k++)
                            {
                                Bit81 A = new Bit81(), B = new Bit81();
                                int   no = IX[k];
                                foreach (var P in basUGLs)
                                {
                                    if (P.rcBit81 is Bit81)
                                    {
                                        if (P.rcBit81.no == no)
                                        {
                                            A |= P.rcBit81;
                                        }
                                        else
                                        {
                                            B |= P.rcBit81;
                                        }
                                    }
                                    else
                                    {
                                        int rc = P.UC.rc;
                                        foreach (var n in P.UC.FreeB.IEGet_BtoNo())
                                        {
                                            if (n == no)
                                            {
                                                A.BPSet(rc);
                                            }
                                            else
                                            {
                                                B.BPSet(rc);
                                            }
                                        }
                                    }
                                }

                                int nOL = (B & A).Count;
                                if (rnk == 0 && nOL < 2)
                                {
                                    goto LNextSet;
                                }
                                if (rnk > 0 && nOL < 1)
                                {
                                    goto LNextSet;
                                }
                                //    WriteLine("---------- no:{0} sz:{1} rnk:{2} nOL:{3} (A-B):{4} (B-A):{5}", no, sz,rnk, nOL, (A-B).Count, (B-A).Count );
                            }
                            //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2
                        }
                    }
                }

                //---------------------------------------------------------------------------------------
LBSFound:
                if (SDK_Ctrl.UGPMan.stageNo == 12 && sz >= 3)// && rnk==1 ){
                {
                    WriteLine("\r sz:{0} rnk:{1} jkc:{2}", sz, rnk, jkC);
                    Check_rcbnCondition(sz, rnk, sz, rcbn36, printB: true);
                    basUGLs.ForEach(P => WriteLine(P.ToString("BaseSet")));
                }

                usedLK.Clear();
                basUGLs.ForEach(P => usedLK.BPSet(P.SrNum)); //IDrc: rc<<17 | 1<<16
                UBasCov UBC = new UBasCov(basUGLs, HB981, sz, usedLK);
                yield return(UBC);

LNextSet:
                continue;
            }
            yield break;
        }
 public void addCoverSet(List <UGLink> covUGLs, Bit981 HC981, Bit981 Can981, int rnk)
 {
     this.covUGLs = covUGLs; this.HC981 = HC981; this.Can981 = Can981; this.rnk = rnk;
 }
 public UBasCov(List <UGLink> basUGLs, Bit981 HB981, int sz, Bit324 usedLK)
 {
     this.basUGLs = basUGLs; this.HB981 = HB981; this.sz = sz; this.usedLK = usedLK;
 }
            public bool Check_BaseSetCondition(Bit981 HB981)   //for sz>=2
            {
                bool niceB = false, E = false;

                jkC++;

                #region There is a link between the link and the other link group
                for (int k = 0; k < sz; k++)
                {
                    UGLink UGL  = basUGLs[k];
                    Bit981 Bcum = new Bit981();
                    for (int m = 0; m < sz; m++)
                    {
                        if (m == k)
                        {
                            continue;
                        }
                        Bcum |= basUGLs[m].rcbn2;
                    }
                    if ((Bcum & UGL.rcbn_conn2).Count <= 0)
                    {
                        goto Lreturn;                                  //false
                    }
                }
                #endregion
                GeneralLogicGen.ChkBas3++;                           //*****
                #region Every element of the number(#no) has a link
                //それぞれのリンクは、その他のリンク群と連結する。
                //リンクしないセルはrnk個数以下でなければならない。
                //if(E) for(int n=0; n<9; n++ ) WriteLine(HB981.tfx27Lst[n].ToBitString(27));
                Bit981 Q9 = HB981.Copy();
                usedLKLst.ForEach(p => HB981.tfxReset(p & 0xF, p >> 4));
                usedLKIgnrLst.ForEach(p => HB981.tfxReset(p & 0xF, p >> 4));
                //if(E) for(int n=0; n<9; n++ ) WriteLine(HB981.tfx27Lst[n].ToBitString(27));
                int QPP = 0;
                foreach (var no in noB.IEGet_BtoNo())
                {
                    Bit81 Q = Q9._BQ[no];//new Bit81(HB981._BQ[no]);
                    //if(E) WriteLine( "HB981.tfxLst[no]: "+HB981.tfx27Lst[no].ToBitString(27) );
                    foreach (var tfx in HB981.tfx27Lst[no].IEGet_tfb())
                    {
                        int bp = HB981.GetBitPattern_tfnx(no, tfx);
                        if (bp <= 0)
                        {
                            continue;
                        }
                        int nc = bp.BitCount();
                        if (nc >= 2)
                        {
                            if (E)
                            {
                                WriteLine("Q: " + Q.ToString());
                            }
                            foreach (var nx in bp.IEGet_BtoNo())
                            {
                                int rc = tfx.Get_tfx_rc(nx);
                                Q.BPReset(rc);
                            }
                            //if(E) WriteLine("Q: "+Q.ToString() );
                        }
                    }
                    QPP += Q.Count;
                }
                if (QPP <= rnk)
                {
                    niceB = true; goto Lreturn;
                }
                #endregion
                GeneralLogicGen.ChkBas3++;                           //*****

                #region There is a possibility link between the patterns of numbers n1,n2
                //数字間のリンクしないセルは、rnk*2以下でなければならない。
                if (HB981.nzBit.BitCount() >= 2)
                {
                    bool  firstB = true;
                    Bit81 Q      = null;
                    foreach (var n in HB981.nzBit.IEGet_BtoNo())
                    {
                        if (firstB)
                        {
                            Q = HB981._BQ[n]; firstB = false;
                        }
                        else
                        {
                            Q |= HB981._BQ[n];
                        }
                    }
                    foreach (var rc in Q.IEGetRC())
                    {
                        if (HB981.GetBitPattern_rcN(rc).BitCount() >= 2) //セルrcの数字間リンクがあるときは、Q9リセット
                        {
                            foreach (var no in noB.IEGet_BtoNo())
                            {
                                Q9._BQ[no].BPReset(rc);
                            }
                        }
                    }
                    int Q9cc = Q9.BitCount();
                    if (Q9cc <= rnk)
                    {
                        niceB = true; goto Lreturn;
                    }                                          //直接リンクしないセルがrnk以下のときは、次のテストに進む
                    if (Q9cc <= rnk * 2)
                    {
                        GeneralLogicGen.ChkBas1B++;                       //*****
                        foreach (var n1 in Q9.nzBit.IEGet_BtoNo())
                        {
                            foreach (var rc in Q9._BQ[n1].IEGetRC())
                            {
                                foreach (var n2 in Q9.nzBit.IEGet_BtoNo().Where(nx => nx != n1))
                                {
                                    if ((Q9._BQ[n2] & p_connectedCells[rc]).BitCount() == 0)
                                    {
                                        continue;
                                    }
                                    //リンクしないセル間を繋ぐリンクがある(”可能性あり”で次のテストに進む
                                    GeneralLogicGen.ChkBas1A++;           //*****
                                    niceB = true; goto Lreturn;
                                }
                            }
                        }
                    }
                }
                #endregion

                GeneralLogicGen.ChkBas4++;                   //*****
Lreturn:
                return(niceB);
            }
        //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2
        public IEnumerable <UBasCov> IEGet_CoverSet(UBasCov UBC, int rnk)
        {
            if (UGLLst == null)
            {
                yield break;
            }

            List <UGLink> basUGLs = UBC.basUGLs;
            Bit981        HB981   = UBC.HB981;
            Bit324        usedLK  = UBC.usedLK;
            int           nzBit   = HB981.nzBit;
            int           nzBitCC = nzBit.BitCount();
            int           sz      = UBC.sz;

            List <UGLink> UGLCovLst = new List <UGLink>();  // UGLCovLst:candidate link

            #region Create UGLCovLst
            Bit81 Bcmp = HB981.CompressToHitCells();
            foreach (var P in UGLLst.Where(q => !usedLK.IsHit(q.SrNum)))
            {
                if (P.rcBit81 is Bit81) //Row, column, block link
                {
                    if ((nzBit & (1 << P.rcBit81.no)) == 0)
                    {
                        continue;
                    }
                    int B = (HB981._BQ[P.rcBit81.no] & P.rcBit81).BitCount();
                    if (B == 0)
                    {
                        continue;
                    }

                    // if rank:0, the CoverSet has two or more common items
                    if (rnk == 0 && (HB981._BQ[P.rcBit81.no] & P.rcBit81).Count < 2)
                    {
                        continue;
                    }
                    UGLCovLst.Add(P);
                }
                else    //Cell
                {
                    if (nzBitCC <= 1)
                    {
                        continue;
                    }
                    if ((nzBit & P.UC.FreeB) == 0)
                    {
                        continue;
                    }
                    int B = nzBit & P.UC.FreeB;
                    if (B == 0)
                    {
                        continue;
                    }
                    int rc = P.UC.rc;

                    int kcc = 0, kccLim = (rnk == 0)? 2:1;
                    foreach (var no in B.IEGet_BtoNo())
                    {
                        if (!HB981._BQ[no].IsHit(rc))
                        {
                            continue;
                        }
                        if (++kcc >= kccLim)
                        {
                            UGLCovLst.Add(P); break;
                        }
                    }
                }
            }
            #endregion
            if (UGLCovLst.Count < sz + rnk)
            {
                yield break;
            }
            Bit981      HC981  = new Bit981();
            Bit981      HLapB  = new Bit981();
            Bit981      Can981 = new Bit981();
            Combination cmbCvr = new Combination(UGLCovLst.Count, sz + rnk);
            int         nxt    = int.MaxValue;
            while (cmbCvr.Successor(nxt))
            {
                ++GeneralLogicGen.ChkCov1;

                HC981.Clear();
                Array.ForEach(cmbCvr.Index, m => HC981 |= UGLCovLst[m].rcbn2);

                if (!(HB981 - HC981).IsZero())
                {
                    goto LNextSet;                              //BaseSet is covered?
                }
                Bit981 CsubB = HC981 - HB981;
                if (CsubB.IsZero())
                {
                    goto LNextSet;                              //excludable candidates is exist?
                }
                List <UGLink> covUGLs = new List <UGLink>();
                Array.ForEach(cmbCvr.Index, m => covUGLs.Add(UGLCovLst[m]));

                if (rnk == 0)
                {
                    Can981 = CsubB;
                }
                else    //if(rnk>0){
                {
                    bool SolFound = false;
                    foreach (int n in CsubB.nzBit.IEGet_BtoNo())
                    {
                        foreach (int rc in CsubB._BQ[n].IEGetRC())
                        {
                            int kc = covUGLs.Count(Q => Q.IsHit(n, rc));
                            if (kc == rnk + 1)
                            {
                                Can981.BPSet(n, rc);
                                SolFound = true;
                            }
                        }
                    }
                    if (!SolFound)
                    {
                        continue;
                    }
                }
                ++GeneralLogicGen.ChkCov2;                       //*****

                UBC.addCoverSet(covUGLs, HC981, Can981, rnk);
                yield return(UBC);

LNextSet:
                continue;
            }
            yield break;
        }