private int GroupedNLEx_CheckSolution(USuperLink GNL_Result, ref int contDiscontF)
        {
            bool SolFound = false;

            GroupedLink GLKnxt = GNL_Result.resultGLK;

            if (GLKnxt == null)
            {
                return(-1);                                     //Not established
            }
            List <GroupedLink> SolLst = Convert_ChainToList_GNL(GNL_Result);

            if (SolLst == null || SolLst.Count < 2)
            {
                return(-1);                                    //Not established
            }
            GroupedLink GLKorg  = SolLst[0];
            bool        SolType = Check_SuperLinkSequence(GLKnxt, GLKorg); //true:Continuous  false:DisContinuous

            contDiscontF = SolType? 1: 2;

            if (SolType)         //==================== continuous ====================
            {
                Bit81 UsedCs = SolLst.Aggregate(new Bit81(), (Q, P) => Q | P.UGCellsB.B81);

                foreach (var LK in SolLst.Where(P => (P.type == W)))
                {
                    int   noB   = 1 << LK.no;
                    Bit81 SolBP = new Bit81();
                    LK.UGCellsA.ForEach(P => { if ((P.FreeB & noB) > 0)
                                               {
                                                   SolBP.BPSet(P.rc);
                                               }
                                        });
                    LK.UGCellsB.ForEach(P => { if ((P.FreeB & noB) > 0)
                                               {
                                                   SolBP.BPSet(P.rc);
                                               }
                                        });
                    if (SolBP.BitCount() <= 1)
                    {
                        continue;
                    }
                    foreach (var P in pBDL.Where(p => (p.FreeB & noB) > 0))
                    {
                        if (UsedCs.IsHit(P.rc))
                        {
                            continue;
                        }
                        if (!(SolBP - ConnectedCells[P.rc]).IsZero())
                        {
                            continue;
                        }
                        if ((P.FreeB & noB) == 0)
                        {
                            continue;
                        }
                        P.CancelB |= noB; �@�@//exclusion digit
Example #2
0
        //RCC
        public int  Get_AlsAlsRcc(UALS UA, UALS UB)
        {
            if ((UA.FreeB & UB.FreeB) == 0)
            {
                return(0);                                 //no common digit
            }
            if (!(UA.B81 & UB.B81).IsZero())
            {
                return(0);                                 //overlaps 
            }
            if ((UA.rcbFilter & UB.B81).IsZero())
            {
                return(0);                                 //no contact
            }
            int RCC = 0, Dir = UA.rcbDir & UB.rcbDir;

            //[definition] rcbDir |= ( (1<<(P.b+18)) | (1<<(P.c+9)) | (1<<(P.r)) );
            foreach (int tfx in Dir.IEGet_BtoNo(27))
            {
                Bit81 ComH = pHouseCells[tfx];
                int   FrAi = 0, FrAo = 0, FrBi = 0, FrBo = 0;
                UA.UCellLst.ForEach(P => {
                    if (ComH.IsHit(P.rc))
                    {
                        FrAi |= P.FreeB;
                    }
                    else
                    {
                        FrAo |= P.FreeB;
                    }
                });
                UB.UCellLst.ForEach(P => {
                    if (ComH.IsHit(P.rc))
                    {
                        FrBi |= P.FreeB;
                    }
                    else
                    {
                        FrBo |= P.FreeB;
                    }
                });
                RCC |= (FrAi.DifSet(FrAo)) & (FrBi.DifSet(FrBo));    //RCC
            }
            return(RCC);
        }
        private IEnumerable <Bit81[]> _GetXYChain(List <int> LKRec)
        {
            List <UCell> TBDbv = pBDL.FindAll(p => (p.FreeBC == 2));                //Extract BV_Cell(BV:bivalue).

            foreach (var PS in TBDbv)                                               //Choose one BV_Cell(=>PS)
            {
                int rcS = PS.rc;
                foreach (var no in PS.FreeB.IEGet_BtoNo())                          //Choose one digit(in PS)
                {
                    int     noB = (1 << no);
                    Bit81[] CRL = new Bit81[2];
                    CRL[0]    = new Bit81();                                        //Position of the target digit to be concatenated
                    CRL[1]    = new Bit81();                                        //Position of other digits to be connected
                    CRL[0].ID = rcS; CRL[1].ID = no;

                    Bit81       CnctdCs = ConnectedCells[rcS];                      //Associated cells group of starting cell
                    Queue <int> rcQue   = new Queue <int>();
                    int         no0     = pBDL[rcS].FreeB.BitReset(no).BitToNum();  //The other digit of the starting cell
                    rcQue.Enqueue((no0 << 8) | rcS);

                    LKRec.Clear();
                    while (rcQue.Count > 0)                                            //Extend the chain step by step
                    {
                        int rcX = rcQue.Dequeue();
                        int no1 = rcX >> 8, rc1 = rcX & 0xFF;
                        foreach (var LK in CeLKMan.IEGetRcNoType(rc1, no1, 1))       //strongLink connected with rc1, #no
                        {
                            int rc2 = LK.rc2;
                            if (pBDL[rc2].FreeBC != 2)
                            {
                                continue;                                           //bivalue?
                            }
                            if (CRL[0].IsHit(rc2) || CRL[1].IsHit(rc2))
                            {
                                continue;                                           //Different from colored cells?
                            }
                            //Exclude cells associated with the starting cell and having the same digit
                            if (CnctdCs.IsHit(rc2) && (pBDL[rc2].FreeB & noB) > 0)
                            {
                                continue;
                            }

                            int no2 = (pBDL[rc2].FreeB.BitReset(no1)).BitToNum();   //other digit
                            int nx  = (no2 == no)? 0: 1;
                            CRL[nx].BPSet(rc2);
                            rcQue.Enqueue((no2 << 8) | rc2);                          //Put the next [Digit&Cell] in Queue
                            LKRec.Add((rc1 << 8 | rc2));                              //Record Link
                        }
                    }
                    if (CRL[0].Count > 0 || CRL[1].Count > 0)
                    {
                        yield return(CRL);
                    }
                }
            }
            yield break;
        }
        private bool CheckUsed(Bit81 UsedPre, GroupedLink GLKnxt)
        {
            Bit81 BP = GLKnxt.UGCellsB.B81;

            if (GLKnxt is ALSLink)
            {
                BP -= (GLKnxt.UGCellsA.B81);
            }
            return(UsedPre.IsHit(BP)); //Overlap Check
        }
        private bool _NL_Search(UCellLink LK0, UCellLink LKpre, Stack <UCellLink> SolStack, Bit81 UsedCells, int szCtrl)
        {
            if (szCtrl <= 0)
            {
                return(false);
            }

            foreach (var LKnxt in CeLKMan.IEGet_CeCeSeq(LKpre))     //links that satisfy concatenation conditions
            {
                int rc2Nxt = LKnxt.rc2;
                if (UsedCells.IsHit(rc2Nxt))
                {
                    continue; //UsedCells does not include Origin Cell
                }
                {             //===== Chain Search =====
                    SolStack.Push(LKnxt);
                    //___Debug_Print_NLChain(SolStack);
                    if (rc2Nxt == LK0.rc1 && szCtrl == 1)
                    {
                        if (SolStack.Count > 2)                                               //Loop was formed (the next cell matches the Origin Cell)
                        {
                            int SolType = _NL_CheckSolution(LK0, LKnxt, SolStack, UsedCells); //Solved?
                            if (SolType > 0)
                            {
                                if (SolInfoB)
                                {
                                    _NL_SolResult(LK0, LKnxt, SolStack, SolType);
                                }

                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(false))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                    else
                    {
                        Bit81 UsedCellsNxt = UsedCells | (new Bit81(rc2Nxt));       //Create a new bit expression of used cell
                        _NL_Search(LK0, LKnxt, SolStack, UsedCellsNxt, szCtrl - 1); //Next step Search(recursive call
                        if (SolCode > 0)
                        {
                            return(true);
                        }
                    }
                    SolStack.Pop();                                 //Failure(Cancel link extension processing)
                } //-----------------------------
            }
            return(false);
        }
Example #6
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;
        }
Example #7
0
        private void _DeathBlossom_SolResult(List <LinkCellALS> LKCAsol, UCell SC, int no, bool stmLink = false)
        {
            string st0 = "ALS Death Blossom";

            if (stmLink)
            {
                st0 += "Ext";
            }
            Color cr = _ColorsLst[0];////Colors.Gold;

            SC.SetNoBBgColor(SC.FreeB, AttCr3, cr);
            string st = $"\r Cell r{(SC.r+1)}c{(SC.c+1)} #{SC.FreeB.ToBitStringNZ(9)}";
            bool   Overlap = false;
            Bit81  OV = new Bit81();
            int    k = 0, noB = (1 << no);

            foreach (var LK in LKCAsol)
            {
                int noB2 = 1 << LK.nRCC;
                cr = _ColorsLst[++k];
                LK.ALS.UCellLst.ForEach(P => {
                    P.SetNoBBgColor(noB, AttCr, cr);
                    P.SetNoBBgColor(noB2, AttCr3, cr);
                    if (OV.IsHit(P.rc))
                    {
                        Overlap = true;
                    }
                    OV.BPSet(P.rc);
                });
                st += $"\r     -#{(LK.nRCC+1)}-ALS{k} {LK.ALS.ToStringRCN()}";
            }

            if (Overlap)
            {
                st0 += " [overlapping]";
            }
            Result = st0;
            if (SolInfoB)
            {
                ResultLong = st0 + st;
            }
        }
        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;
        }
Example #9
0
        public int GetBitPattern_tfnx(int n, int tfx)
        {
            Bit81 P = _BQ[n];
            int   r = 0, c = 0, tp = tfx / 9, fx = tfx % 9, bp = 0;

            for (int nx = 0; nx < 9; nx++)
            {
                switch (tp)
                {
                case 0: r = fx; c = nx; break;                                       //row

                case 1: r = nx; c = fx; break;                                       //column

                case 2: r = (fx / 3) * 3 + nx / 3; c = (fx % 3) * 3 + nx % 3; break; //block
                }
                if (P.IsHit(r * 9 + c))
                {
                    bp |= 1 << nx;
                }
            }
            return(bp);
        }
        public bool IsLinked9(Bit81 HB81)
        {
            Bit81 Colored = new Bit81(), Processed = new Bit81();
            int   rc0 = HB81.FindFirstrc();

            Colored.BPSet(rc0);
            while (true)
            {
                Bit81 T = Colored - Processed;
                if ((rc0 = T.FindFirstrc()) < 0)
                {
                    break;
                }

                Processed.BPSet(rc0);
                Colored |= HB81 & pConnectedCells[rc0];
                if (HB81.IsHit(rc0))
                {
                    Colored.BPSet(rc0);
                }
            }
            return((HB81 - Colored).IsZero());
        }
        public bool ExtKrFishSub(int sz, int no, int FMSize, bool FinnedF)
        {
            int BaseSel = 0x7FFFFFF, CoverSel = 0x7FFFFFF;
            int noB = (1 << no);

            string  krfSolMsg = "";
            FishMan FMan      = new FishMan(this, FMSize, no, sz, (sz >= 3));

            foreach (var Bas in FMan.IEGet_BaseSet(BaseSel, FinnedF:FinnedF))     //Generate BaseSet
            {
                foreach (var Cov in FMan.IEGet_CoverSet(Bas, CoverSel, FinnedF))  //Generate CoverSet
                {
                    Bit81 FinB81 = Cov.FinB81;
                    //dbCC++;//##############
                    if (FinnedF != FinB81.IsZero())
                    {
                        //WriteLine( $"dbCC:{dbCC} \rbas:{Bas.BaseB81}\rCov:{Cov.CoverB81}" );//######
                        //WriteLine( $"Bas.HouseB:{Bas.HouseB.ToBitString27()}");
                        //WriteLine( $"Cov.HouseB:{Cov.HouseC.ToBitString27()}");

                        Bit81 UsedB = Bas.BaseB81;
                        foreach (var Hb in Bas.HouseB.IEGet_BtoNo(27))
                        {
                            Bit81 E = Bas.BaseB81 & HouseCells[Hb];
                            if (FinnedF)
                            {
                                E |= FinB81;                                    //Finned
                            }
                            if (E.IsZero())
                            {
                                continue;
                            }

                            foreach (var P in pBDL.Where(p => !UsedB.IsHit(p.rc)))
                            {
                                foreach (var noZ in P.FreeB.IEGet_BtoNo())
                                {
                                    int        noZb = (1 << noZ);
                                    USuperLink USLK = pSprLKsMan.get_L2SprLK(P.rc, noZ, FullSearchB: false, DevelopB: false);                             //#####
                                    //WriteLine( $" USuperLink rc:{P.rc} no:{noZ+1}" );
                                    if (!USLK.SolFound)
                                    {
                                        continue;
                                    }
                                    Bit81 Ef = E - USLK.Qfalse[no];
                                    if (!Ef.IsZero())
                                    {
                                        continue;
                                    }

                                    //Accurate analysis
                                    USLK = pSprLKsMan.get_L2SprLK(P.rc, noZ, FullSearchB: true, DevelopB: false);                             //#####
                                    Ef   = E - USLK.Qfalse[no];
                                    if (!Ef.IsZero())
                                    {
                                        continue;
                                    }
                                    P.CancelB |= noZb;
                                    SolCode    = 2;

                                    if (SolInfoB)
                                    {
                                        _KrFish_FishResult(no, sz, Bas, Cov);
                                        krfSolMsg += $"\r{_krfMsg}  r{(P.r+1)}c{(P.c+1)}/{(noZ+1)} is false";
                                        foreach (var rc in E.IEGet_rc())
                                        {
                                            krfSolMsg += "\r" + pSprLKsMan._GenMessage2false(USLK, pBDL[rc], no);
                                        }
                                    }
                                    //goto LSolFound;
                                }
                            }

                            //	LSolFound:
                            if (SolCode > 0)
                            {
                                if (SolInfoB)
                                {
                                    extRes = krfSolMsg;
                                }
                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(false))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }
Example #12
0
        //Skyscraper is an algorithm consisting of two StrongLinks.
        //http://csdenpe.web.fc2.com/page40.html
        public bool Skyscraper()
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);                                             //Generate StrongLink

            for (int no = 0; no < 9; no++)
            {
                int noB   = (1 << no);
                var SSLst = CeLKMan.IEGetNoType(no, 1).ToList();         //select only StrongLink of #no
                if (SSLst.Count <= 2)
                {
                    continue;
                }

                var prm  = new Permutation(SSLst.Count, 2);
                int nxtX = 99;
                while (prm.Successor(nxtX))
                {
                    UCellLink UCLa = SSLst[prm.Index[0]], UCLb = SSLst[prm.Index[1]];

                    nxtX = 1;
                    if (UCLa.ID > UCLb.ID)
                    {
                        nxtX = 0; continue;
                    }                                                   //next permutation data skip_generation(nxtX=0)
                    if ((UCLa.B81 | UCLb.B81).Count != 4)
                    {
                        continue;                                       //All cells are different?
                    }
                    Bit81 ConA1 = ConnectedCells[UCLa.rc1];             //ConA1:cell group related to cell rc1
                    if (!ConA1.IsHit(UCLb.rc1) || ConA1.IsHit(UCLb.rc2))
                    {
                        continue;
                    }

                    Bit81 ConA2 = ConnectedCells[UCLa.rc2];               //ConA2:cell group related to cell rc1
                    if (ConA2.IsHit(UCLb.rc1) || ConA2.IsHit(UCLb.rc2))
                    {
                        continue;
                    }
                    //Only UCLa.rc1 and UCLb.rc1 belong to the same house.

                    Bit81 ELM = ConA2 & ConnectedCells[UCLb.rc2];
                    ELM -= (ConA1 | ConnectedCells[UCLb.rc1]);          //ELM:eliminatable cells

                    bool SSfound = false;
                    foreach (UCell P in ELM.IEGetUCeNoB(pBDL, noB))
                    {
                        P.CancelB = P.FreeB & noB; SSfound = true;
                    }
                    if (!SSfound)
                    {
                        continue;           //Skyscraper found
                    }
                    #region Result
                    SolCode = 2;
                    if (SolInfoB)
                    {
                        pBDL[UCLa.rc1].SetNoBBgColor(noB, AttCr, SolBkCr);
                        pBDL[UCLa.rc2].SetNoBBgColor(noB, AttCr, SolBkCr);
                        pBDL[UCLb.rc1].SetNoBBgColor(noB, AttCr, SolBkCr);
                        pBDL[UCLb.rc2].SetNoBBgColor(noB, AttCr, SolBkCr);

                        string msg = "\r", msg2 = "";
                        msg += $"  on {(no+1)} in {UCLa.rc1.ToRCNCLString()} {UCLb.rc1.ToRCNCLString()}";
                        msg += $"\r  connected by {UCLa.rc2.ToRCNCLString()} {UCLb.rc2.ToRCNCLString()}";
                        msg += "\r  eliminated ";
                        foreach (UCell P in ELM.IEGetUCeNoB(pBDL, noB))
                        {
                            msg2 += " " + P.rc.ToRCString();
                        }
                        msg2      += " " + msg2.ToString_SameHouseComp();
                        ResultLong = "Skyscraper" + msg + msg2;
                        Result     = $"Skyscraper #{(no+1)} in {msg2}";
                    }
                    else
                    {
                        Result = $"Skyscraper #{(no+1)}";
                    }
                    #endregion Result
                    if (__SimpleAnalizerB__)
                    {
                        return(true);
                    }
                    if (!pAnMan.SnapSaveGP(true))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        private void SearchGroupedLink()
        {
            try{
                UGrCells[] LQ = new UGrCells[3];
                for (int no = 0; no < 9; no++)
                {
                    int   noB   = 1 << no;
                    Bit81 BPnoB = new Bit81(pBDL, noB);

                    //------------------------------------------
                    for (int tfx = 0; tfx < 18; tfx++)
                    {
                        Bit81 BPnoB2 = BPnoB & pHouseCells[tfx];

                        List <Bit81> houseLst = new List <Bit81>();
                        List <int>   tfxLst   = new List <int>();
                        for (int k = 0; k < 9; k++)
                        {
                            int   hx = (tfx < 9)? (k + 9): k;
                            Bit81 BX = BPnoB2 & pHouseCells[hx];
                            if (BX.IsZero())
                            {
                                continue;
                            }
                            houseLst.Add(BX);
                            tfxLst.Add(hx);
                        }
                        for (int k = 0; k < 3; k++)
                        {
                            int hx = (tfx < 9)? (tfx / 3 * 3 + k): ((tfx - 9) / 3 + k * 3);
                            hx += 18;
                            Bit81 BX = BPnoB2 & pHouseCells[hx];
                            if (BX.IsZero())
                            {
                                continue;
                            }
                            houseLst.Add(BX);
                            tfxLst.Add(hx);
                        }

                        if (houseLst.Count < 2)
                        {
                            continue;
                        }
                        Permutation prm = new Permutation(houseLst.Count, 2);
                        while (prm.Successor())
                        {
                            int   na = prm.Index[0], nb = prm.Index[1];
                            Bit81 HA = houseLst[na];
                            Bit81 HB = houseLst[nb];
                            if (!(HA & HB).IsZero())
                            {
                                continue;
                            }
                            UGrCells LA = new UGrCells(tfxLst[na], no);
                            UGrCells LB = new UGrCells(tfxLst[nb], no);
                            foreach (var P in HA.IEGetUCeNoB(pBDL, 0x1FF))
                            {
                                LA.Add(P);
                            }
                            foreach (var P in HB.IEGetUCeNoB(pBDL, 0x1FF))
                            {
                                LB.Add(P);
                            }
                            SetGroupedLink(tfxLst[nb], W, no, LA, LB);
                            if (!(BPnoB2 - (HA | HB)).IsZero())
                            {
                                continue;
                            }
                            SetGroupedLink(tfxLst[nb], S, no, LA, LB);
                        }
                    }

                    //------------------------------------------
                    for (int tfx = 18; tfx < 27; tfx++)
                    {
                        int bx = tfx - 18;
                        int b0 = (bx / 3 * 27 + (bx % 3) * 3); //Cell number at the top left of the block

                        Bit81        BPnoB2   = BPnoB & pHouseCells[tfx];
                        List <Bit81> houseLst = new List <Bit81>();
                        List <int>   tfxLst   = new List <int>();
                        for (int k = 0; k < 3; k++)
                        {
                            int   r0 = (b0 / 9 + k);
                            Bit81 BX = BPnoB2 & pHouseCells[r0];
                            if (BX.IsZero())
                            {
                                continue;
                            }
                            houseLst.Add(BX);
                            tfxLst.Add(r0);
                        }
                        for (int k = 0; k < 3; k++)
                        {
                            int   c0 = (b0 % 9) + k;
                            Bit81 BX = BPnoB2 & pHouseCells[c0 + 9];
                            if (BX.IsZero())
                            {
                                continue;
                            }
                            houseLst.Add(BX);
                            tfxLst.Add(c0 + 9);
                        }

                        if (houseLst.Count >= 2)
                        {
                            Permutation prm = new Permutation(houseLst.Count, 2);
                            while (prm.Successor())
                            {
                                int   na = prm.Index[0], nb = prm.Index[1];
                                Bit81 HA = houseLst[na];
                                Bit81 HB = houseLst[nb] - HA;
                                if (HB.IsZero())
                                {
                                    continue;
                                }
                                UGrCells LA = new UGrCells(tfxLst[na], no);
                                UGrCells LB = new UGrCells(tfxLst[nb], no);
                                foreach (var P in HA.IEGetUCeNoB(pBDL, 0x1FF))
                                {
                                    LA.Add(P);
                                }
                                foreach (var P in HB.IEGetUCeNoB(pBDL, 0x1FF))
                                {
                                    LB.Add(P);
                                }
                                SetGroupedLink(tfxLst[nb], W, no, LA, LB);
                                if (!(BPnoB2 - (HA | HB)).IsZero())
                                {
                                    continue;
                                }
                                SetGroupedLink(tfxLst[nb], S, no, LA, LB);
                            }
                        }
                        if (houseLst.Count >= 1)
                        {
                            for (int na = 0; na < houseLst.Count; na++)
                            {
                                Bit81    HA = houseLst[na];
                                UGrCells LA = new UGrCells(tfxLst[na], no);
                                foreach (var P in HA.IEGetUCeNoB(pBDL, 0x1FF))
                                {
                                    LA.Add(P);
                                }
                                foreach (var rc in BPnoB2.IEGet_rc())
                                {
                                    if (HA.IsHit(rc))
                                    {
                                        continue;
                                    }
                                    UGrCells LB = new UGrCells(-9, no, pBDL[rc]);
                                    SetGroupedLink(tfxLst[na], W, no, LA, LB);
                                    SetGroupedLink(-9, W, no, LB, LA);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex) {
                WriteLine(ex.Message);
                WriteLine(ex.StackTrace);
            }
        }
Example #14
0
        private bool _XYZwingALSSub(int wsz)    //simple UVWXYZwing
        {
            List <UCell> FBCX = pBDL.FindAll(p => p.FreeBC == wsz);

            if (FBCX.Count == 0)
            {
                return(false);
            }

            foreach (var P0 in FBCX)    //Forcused Cell
            {
                int b0 = P0.b;          //Forcused Block

                for (int no = 0; no < 9; no++)
                {
                    int noB = 1 << no;

                    Bit81 P0con = (new Bit81(pBDL, noB)) & ConnectedCells[P0.rc];
                    Bit81 Pin   = P0con & HouseCells[18 + b0];

                    for (int dir = 0; dir < 2; dir++)                                //dir 0:row 1:col
                    {
                        int   rcDir = (dir == 0)? P0.r: (9 + P0.c);
                        Bit81 Pin2  = Pin - HouseCells[rcDir];                   //ALS candidate position in the block
                        if (Pin2.IsZero())
                        {
                            continue;
                        }

                        Bit81 Pout = (P0con & HouseCells[rcDir]) - HouseCells[18 + P0.b];    //ALS candidate position outside the block
                        foreach (var ALSout in ALSMan.IEGetCellInHouse(1, noB, Pout, rcDir)) //ALS out of Forcused Block
                        {
                            int   FreeBOut2 = ALSout.FreeB.DifSet(noB);
                            Bit81 EOut      = new Bit81();                      //#no existence position(outer-ALS)
                            foreach (var P in ALSout.UCellLst.Where(p => (p.FreeB & noB) > 0))
                            {
                                EOut.BPSet(P.rc);
                            }

                            foreach (var ALSin in ALSMan.IEGetCellInHouse(1, noB, Pin2, 18 + b0))
                            {
                                int FreeBin2 = ALSin.FreeB.DifSet(noB);

                                Bit81 Ein = new Bit81();                          //#no existence position(inner-ALS)
                                foreach (var P in ALSin.UCellLst.Where(p => (p.FreeB & noB) > 0))
                                {
                                    Ein.BPSet(P.rc);
                                }

                                int Cover = P0.FreeB.DifSet(ALSout.FreeB | ALSin.FreeB);
                                if (Cover != 0)
                                {
                                    continue;                                   //Numbers in inner-ALS and outer-ALS cover numbers in the Forcused cell
                                }
                                Bit81 Epat = EOut | Ein;                        //Cells covered by excluded Cells&Digit
                                if (Epat.IsZero())
                                {
                                    continue;
                                }
                                bool   SolFound = false;
                                string msg3     = "";

                                int FreeBin3 = P0.FreeB.DifSet(FreeBOut2 | FreeBin2);
                                foreach (var E in pBDL.Where(p => (p.FreeB & noB) > 0))
                                {
                                    if (E.rc == P0.rc || Pout.IsHit(E.rc) || Pin2.IsHit(E.rc))
                                    {
                                        continue;
                                    }
                                    if (!(Epat - ConnectedCells[E.rc]).IsZero())
                                    {
                                        continue;
                                    }
                                    if (FreeBin3 > 0 && !ConnectedCells[E.rc].IsHit(P0.rc))
                                    {
                                        continue;
                                    }
                                    E.CancelB = noB; SolFound = true;
                                    msg3     += " " + E.rc.ToRCString();
                                }

                                if (SolFound)
                                {
                                    SolCode = 2;
                                    string[] xyzWingName = { "XYZ-Wing", "WXYZ-Wing", "VWXYZ-Wing", "UVWXYZ-Wing" };
                                    string   SolMsg      = xyzWingName[wsz - 3] + "(ALS)";

                                    if (SolInfoB)
                                    {
                                        P0.SetNoBBgColor(P0.FreeB, AttCr, SolBkCr2);
                                        foreach (var P in ALSin.UCellLst)
                                        {
                                            P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr);
                                        }
                                        foreach (var P in ALSout.UCellLst)
                                        {
                                            P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr);
                                        }

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

                                        Result     = SolMsg + msg0 + msg1 + msg2;
                                        ResultLong = SolMsg + "\r" + msg0 + "\r   " + msg1 + "\r  " + msg2 + "\r Eliminated: " + msg3.ToString_SameHouseComp();
                                    }

                                    if (__SimpleAnalizerB__)
                                    {
                                        return(true);
                                    }
                                    if (!pAnMan.SnapSaveGP(true))
                                    {
                                        return(true);
                                    }
                                    foreach (var E in pBDL.Where(p => (p.FreeB & noB) > 0))
                                    {
                                        E.CancelB = 0;
                                    }
                                    SolFound = false;
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }
        private int _GroupedNL_CheckSolution(GroupedLink GLK0, GroupedLink GLKnxt,
                                             Stack <GroupedLink> SolStack, Bit81 UsedCs)
        {
            bool SolFound = false;
            int  SolType  = pSprLKsMan.Check_SuperLinkSequence(GLKnxt, GLK0)? 1: 2; //1:Continuous 2:DisContinuous

            if (SolType == 1)                                                       //<>continuous
            {
                List <GroupedLink> SolLst = SolStack.ToList();
                //___Debug_Print_GNLChain(SolStack);

                SolLst.Reverse();
                SolLst.Add(GLK0);

                Bit81 UsedCsTmp = new Bit81(UsedCs);
                SetUsed(ref UsedCsTmp, GLKnxt);

                foreach (var LK in SolLst.Where(P => (P.type == W)))
                {
                    int   noB   = 1 << LK.no;
                    Bit81 SolBP = new Bit81();

                    LK.UGCellsA.ForEach(P => { if ((P.FreeB & noB) > 0)
                                               {
                                                   SolBP.BPSet(P.rc);
                                               }
                                        });
                    LK.UGCellsB.ForEach(P => { if ((P.FreeB & noB) > 0)
                                               {
                                                   SolBP.BPSet(P.rc);
                                               }
                                        });
                    if (SolBP.BitCount() <= 1)
                    {
                        continue;
                    }
                    foreach (var P in pBDL.Where(p => (p.FreeB & noB) > 0))
                    {
                        if (UsedCsTmp.IsHit(P.rc))
                        {
                            continue;
                        }
                        if (!(SolBP - ConnectedCells[P.rc]).IsZero())
                        {
                            continue;
                        }
                        if ((P.FreeB & noB) == 0)
                        {
                            continue;
                        }
                        P.CancelB |= noB;   //exclusion digit
                            SolFound = true;
                    }
                }

                var LKpre = SolLst[0];
                foreach (var LK in SolLst.Skip(1))
                {
                    if (LKpre.type == S && LK.type == S && LK.UGCellsA.Count == 1)
                    {
                        var P    = pBDL[LK.UGCellsA[0].rc]; //(for MultiAns code)
                        int noB2 = P.FreeB - ((1 << LKpre.no2) | (1 << LK.no));
                        if (noB2 > 0)
                        {
                            P.CancelB |= noB2; SolFound = true;
                        }
                    }
                    LKpre = LK;
                }
                if (SolFound)
                {
                    SolCode = 1;
                }
            }
            else
            {
                                                         //<>discontinuous
                int   dcTyp = GLK0.type * 10 + GLKnxt.type;
                UCell P     = pBDL[GLK0.UGCellsA[0].rc]; //(for MultiAns code)
                switch (dcTyp)
                {
                case 11:
                    P.FixedNo = GLK0.no + 1;        //Cell number determination
                    P.CancelB = P.FreeB.DifSet(1 << (GLK0.no));
                    SolCode   = 1; SolFound = true; //(1:Fixed)
                    break;

                case 12: P.CancelB = 1 << GLKnxt.no; SolCode = 2; SolFound = true; break;//(2:Exclude from candidates)

                case 21: P.CancelB = 1 << GLK0.no; SolCode = 2; SolFound = true; break;

                case 22:
                    if (GLK0.no == GLKnxt.no)
                    {
                        P.CancelB = 1 << GLK0.no; SolFound = true; SolCode = 2;
                    }
                    break;
                }
            }

            if (SolFound)
            {
                return(SolType);
            }
            return(-1);
        }
        private int _NL_CheckSolution(UCellLink LK0, UCellLink LKnxt, Stack <UCellLink> SolStack, Bit81 UsedCells)
        {
            bool SolFound = false;
            int  SolType  = CeLKMan.Check_CellCellSequence(LKnxt, LK0)? 1: 2; //1:Continuous 2:DisContinuous

            if (SolType == 1)                                                 //===== continuous =====
            //=== Change WeakLink to StrongLink
            {
                List <UCellLink> SolLst     = SolStack.ToList();
                Bit81            UsedCellsT = UsedCells | (new Bit81(LK0.rc1));
                foreach (var L in SolLst)
                {
                    int noB = 1 << L.no;
                    foreach (var P in pBDL.IEGetCellInHouse(L.tfx, noB))
                    {
                        if (UsedCellsT.IsHit(P.rc))
                        {
                            continue;
                        }
                        P.CancelB |= noB;
                        SolFound   = true;
                    }
                }

                //=== S-S (There are no other numbers)
                SolLst.Reverse();
                SolLst.Add(LK0);
                var LKpre = SolLst[0];
                foreach (var LK in SolLst.Skip(1))
                {
                    if (LKpre.type == 1 && LK.type == 1) //S-S
                    {
                        UCell P   = pBDL[LK.rc1];
                        int   noB = P.FreeB.DifSet((1 << LKpre.no) | (1 << LK.no));
                        if (noB > 0)
                        {
                            P.CancelB = noB; SolFound = true;
                        }
                    }
                    LKpre = LK;
                }
                if (SolFound)
                {
                    SolCode = 2;
                }
            }
            else if (SolType == 2)               //===== discontinuous =====
            {
                UCell P     = pBDL[LK0.UCe1.rc]; //(for MultiAns code)
                int   dcTyp = LK0.type * 10 + LKnxt.type;
                switch (dcTyp)
                {
                case 11:
                    P.FixedNo = LK0.no + 1;         //Cell number determination
                    P.CancelB = P.FreeB.DifSet(1 << (LK0.no));
                    SolCode   = 1; SolFound = true; //(1:Fixed)
                    break;

                case 12: P.CancelB = 1 << LKnxt.no; SolCode = 2; SolFound = true; break;//(2:Exclude from candidates)

                case 21: P.CancelB = 1 << LK0.no; SolCode = 2; SolFound = true; break;

                case 22:
                    if (LK0.no == LKnxt.no)
                    {
                        P.CancelB = 1 << LK0.no; SolFound = true; SolCode = 2;
                    }
                    break;
                }
            }
            if (SolFound)
            {
                return(SolType);
            }
            return(-1);
        }