Пример #1
0
        private IEnumerable <Bit81[]> _RPColoring( )
        {
            if (BVCellLst.Count < 4)
            {
                yield break;
            }

            Bit81 TBD = new Bit81();

            BVCellLst.ForEach(p => TBD.BPSet(p.rc));

            int rc1;

            while ((rc1 = TBD.FindFirstrc()) >= 0)
            {
                Bit81[] CRL = new Bit81[2];
                CRL[0] = new Bit81(); CRL[1] = new Bit81();
                Queue <int> rcQue = new Queue <int>();
                rcQue.Enqueue(rc1 << 1);
                CRL[0].BPSet(rc1);
                int FreeB = pBDL[rc1].FreeB;
                CRL[0].ID = FreeB;

                while (rcQue.Count > 0)
                {
                    int rcX = rcQue.Dequeue();
                    int kx  = 1 - (rcX & 1);
                    rc1 = rcX >> 1;
                    TBD.BPReset(rc1);

                    Bit81 Chain = TBD & ConnectedCells[rc1];
                    foreach (var rc2 in Chain.IEGet_rc())
                    {
                        if (!TBD.IsHit(rc2))
                        {
                            continue;
                        }
                        if (pBDL[rc2].FreeB != FreeB)
                        {
                            continue;
                        }
                        rcQue.Enqueue((rc2 << 1) | kx);
                        CRL[kx].BPSet(rc2);
                        TBD.BPReset(rc2);
                    }
                }
                yield return(CRL);
            }
            yield break;
        }
Пример #2
0
        static public Bit81[] HouseCells;        //Row(0-8) Collumn(9-17) Block(18-26)

        static private void Create_ConnectedCells()
        {
            if (ConnectedCells != null)
            {
                return;
            }
            ConnectedCells = new Bit81[81];
            //ConnectedCellsRev = new Bit81[81];

            for (int rc = 0; rc < 81; rc++)
            {
                Bit81 BS = new Bit81();
                foreach (var q in __IEGetCellsConnectedRC(rc).Where(q => q != rc))
                {
                    BS.BPSet(q);
                }
                BS.BPReset(rc);

                ConnectedCells[rc] = BS;
                //ConnectedCellsRev[rc] = BS ^ 0x7FFFFFF;
            }

            HouseCells = new Bit81[27];
            for (int tfx = 0; tfx < 27; tfx++)
            {
                Bit81 tmp = new Bit81();
                foreach (var q in __IEGetCellInHouse(tfx))
                {
                    tmp.BPSet(q);
                }
                HouseCells[tfx] = tmp;
            }
        }
        private IEnumerable <Bit81[]> _Coloring(int no)
        {
            Bit81[] CRL = new Bit81[2];
            CRL[0] = new Bit81(); CRL[1] = new Bit81();
            Bit81 TBD = new Bit81(pBDL, (1 << no));
            int   rc1 = TBD.FindFirstrc();

            while (rc1 >= 0)
            {
                Queue <int> rcQue = new Queue <int>();
                rcQue.Enqueue(rc1 << 1);
                CRL[0].BPSet(rc1);
                TBD.BPReset(rc1);
                while (rcQue.Count > 0)
                {
                    rc1 = rcQue.Dequeue();
                    int kx = 1 - (rc1 & 1);
                    rc1 >>= 1;
                    TBD.BPReset(rc1);
                    foreach (var P in CeLKMan.IEGetRcNoType(rc1, no, 1))
                    {
                        int rc2 = P.rc2;
                        if (!(CRL[0] | CRL[1]).IsHit(rc2) && TBD.IsHit(rc2))
                        {
                            CRL[kx].BPSet(rc2); rcQue.Enqueue((rc2 << 1) | kx);
                        }
                    }
                }
                yield return(CRL);

                if ((rc1 = TBD.FindFirstrc()) < 0)
                {
                    yield break;
                }
                CRL    = new Bit81[2];
                CRL[0] = new Bit81(); CRL[1] = new Bit81();
            }
            yield break;
        }
        private IEnumerable <Bit81[]> _GetXChain(int no, List <int> LKRec)
        {
            Bit81 TBD = new Bit81(pBDL, (1 << no));

            int rcS;

            while ((rcS = TBD.FindFirstrc()) >= 0)                  //rcS:Set the origin cell.
            {
                TBD.BPReset(rcS);                                   //Reset TBD to Processed.

                //===== Repeatedly coloring processing. initialize =====
                Bit81[] CRL = new Bit81[3];                           //Coloring 2 groups(CRL[0] and CRL[1]).
                CRL[0]    = new Bit81(); CRL[1] = new Bit81(rcS); CRL[2] = new Bit81();
                CRL[0].ID = rcS;
                Queue <int> rcQue = new Queue <int>();
                rcQue.Enqueue((rcS << 1) | 1);                        //(First StrongLink)

                //===== Repeatedly coloring processing. start =====
                LKRec.Clear();                                      //clear chain recorder.
                bool firstLK = true;
                while (rcQue.Count > 0)
                {
                    int rcX = rcQue.Dequeue();                                     //recorded [cell and color]
                    int swF = 1 - (rcX & 1);                                       //next color(inversion S-W)
                    int rc1 = (rcX >> 1);                                          //next cell

                    foreach (var LKx in CeLKMan.IEGetRcNoType(rc1, no, (swF + 1))) //LKx:link connected to cell rc1
                    {
                        int rc2 = LKx.rc2;                                         //anather cell of LKx
                        if ((CRL[0] | CRL[1]).IsHit(rc2))
                        {
                            continue;                               //already colored
                        }
                        CRL[swF].BPSet(rc2);                        //coloring
                        rcQue.Enqueue((rc2 << 1) | swF);            //enqueue(next cell and color)
                        LKRec.Add(rc1 << 8 | rc2);                  //chain record
                        if (firstLK)
                        {
                            CRL[2].BPSet(rc2);                      //record colored cells from rcS(source cell)
                        }
                    }
                    firstLK = false;
                }
                if (CRL[1].Count > 0)
                {
                    yield return(CRL);
                }
                //----- Repeatedly coloring processing. end -----
            }
            yield break;
        }
        //XY-Chain is an algorithm using Locked which occurs in the concatenation of bivalues.
        //http://csdenpe.web.fc2.com/page49.html
        public bool XYChain()
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);                //Generate StrongLink

            List <int> LKRec = new List <int>();

            foreach (var CRL in _GetXYChain(LKRec))
            {
                int rcS = CRL[0].ID, no = CRL[1].ID, noB = (1 << no);

                Bit81 ELM = ConnectedCells[rcS] - (CRL[0] | CRL[1]);
                if (ELM.IsZero())
                {
                    continue;
                }

                Bit81 ELM2     = new Bit81();
                bool  XYChainF = false;
                foreach (var E in ELM.IEGetUCeNoB(pBDL, noB))
                {
                    if (CRL[0].IsHit(ConnectedCells[E.rc]))
                    {
                        E.CancelB = noB; XYChainF = true;
                        ELM2     |= CRL[0] & ConnectedCells[E.rc];
                        break;
                    }
                }
                if (!XYChainF)
                {
                    continue;
                }

                //===== XY-Chain found =====
                SolCode = 2;
                String SolMsg = "XY Chain";
                Result = SolMsg;

                int rcE;
                foreach (var P in ELM2.IEGetUCeNoB(pBDL, noB))
                {
                    P.SetNoBBgColor(noB, AttCr, SolBkCr);
                }
                Bit81 ELM2cpy = ELM2.Copy();
                while ((rcE = ELM2.FindFirstrc()) >= 0)
                {
                    string stR      = "";
                    Bit81  XYchainB = _SelectLink_XYChain(LKRec, rcS, rcE, noB, ref stR) - ELM2cpy;
                    if (SolInfoB)
                    {
                        SolMsg += "\r " + stR;
                    }

                    foreach (var P in XYchainB.IEGetUCeNoB(pBDL, 0x1FF))
                    {
                        P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr2);
                    }
                    ELM2.BPReset(rcE);
                }
                if (SolInfoB)
                {
                    ResultLong = SolMsg;
                }
                pBDL[rcS].SetNoBBgColor(noB, AttCr, SolBkCr);

                if (__SimpleAnalizerB__)
                {
                    return(true);
                }
                if (!pAnMan.SnapSaveGP(true))
                {
                    return(true);
                }
                XYChainF = false;
            }
            return(false);
        }
Пример #6
0
        }                                        //UVWXYZ-wing

        private bool _UVWXYZwing(int wsz)        //simple UVWXYZwing
        {
            if (pAnMan.GStage != GStageMemo)
            {
                GStageMemo = pAnMan.GStage;
                FBCX       = pBDL.FindAll(p => p.FreeBC == wsz);
            }
            if (FBCX.Count == 0)
            {
                return(false);
            }

            bool wingF = false;

            foreach (var P0 in FBCX)                       //focused Cell
            {
                int b0 = P0.b;                             //focused Block
                foreach (int no in P0.FreeB.IEGet_BtoNo()) //focused Digit
                {
                    int   noB   = 1 << no;
                    Bit81 P0con = (new Bit81(pBDL, noB, FreeBC: 2)) & ConnectedCells[P0.rc];
                    Bit81 Pin   = P0con & HouseCells[18 + P0.b];

                    Bit81 Pout = null, Pin2 = null;
                    for (int dir = 0; dir < 2; dir++) //dir 0:row 1:col
                    {
                        int rcDir = (dir == 0)? P0.r: (9 + P0.c);
                        Pin2 = Pin - HouseCells[rcDir];
                        if (Pin2.IsZero())
                        {
                            continue;
                        }
                        Pout = (P0con & HouseCells[rcDir]) - HouseCells[18 + P0.b];
                        if (Pin2.Count + Pout.Count != (wsz - 1))
                        {
                            continue;
                        }

                        int FreeBin  = Pin2.AggregateFreeB(pBDL);
                        int FreeBout = Pout.AggregateFreeB(pBDL);
                        if ((FreeBin | FreeBout) != P0.FreeB)
                        {
                            continue;
                        }
                        Bit81 ELst = HouseCells[rcDir] & HouseCells[18 + P0.b];
                        ELst.BPReset(P0.rc);
                        string msg3 = "";
                        foreach (var E in ELst.IEGet_rc().Select(p => pBDL[p]))
                        {
                            if ((E.FreeB & noB) > 0)
                            {
                                E.CancelB = noB; wingF = true;
                                msg3     += " " + E.rc.ToRCString();
                            }
                        }
                        if (!wingF)
                        {
                            continue;
                        }

                        //--- ...wing found -------------
                        SolCode = 2;
                        string[] xyzWingName = { "XYZ-Wing", "WXYZ-Wing", "VWXYZ-Wing", "UVWXYZ-Wing" };
                        string   SolMsg      = xyzWingName[wsz - 3];

                        if (SolInfoB)
                        {
                            P0.SetNoBBgColor(P0.FreeB, AttCr, SolBkCr2);
                            foreach (var P in Pin2.IEGet_rc().Select(p => pBDL[p]))
                            {
                                P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr);
                            }
                            foreach (var P in Pout.IEGet_rc().Select(p => pBDL[p]))
                            {
                                P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr);
                            }

                            string msg0 = " Pivot: " + P0.rc.ToRCString();
                            string st   = ""; foreach (var rc in Pin2.IEGet_rc())
                            {
                                st += " " + rc.ToRCString();
                            }
                            string msg1 = " in: " + st.ToString_SameHouseComp();
                            st = "";  foreach (var rc in Pout.IEGet_rc())
                            {
                                st += " " + rc.ToRCString();
                            }
                            string msg2 = " out: " + st.ToString_SameHouseComp();
                            st = ""; foreach (var rc in Pin2.IEGet_rc())
                            {
                                st += " " + rc.ToRCString();
                            }

                            ResultLong = SolMsg + "\r" + msg0 + "\r   " + msg1 + "\r  " + msg2 + "\r Eliminated: " + msg3.ToString_SameHouseComp();
                            Result     = SolMsg + msg0 + msg1 + msg2;
                        }
                        if (__SimpleAnalizerB__)
                        {
                            return(true);
                        }
                        if (!pAnMan.SnapSaveGP(true))
                        {
                            return(true);
                        }
                        wingF = false;
                    }
                }
            }
            return(false);
        }
            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);
            }