//X-Chain is an algorithm using Locked which occurs when concatenating strong and weak links.
        //http://csdenpe.web.fc2.com/page48.html
        public bool XChain()
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);                                          //Generate StrongLink

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

                List <int> LKRec = new List <int>();
                foreach (var CRL in _GetXChain(no, LKRec))
                {
                    int rcS = CRL[0].ID;                                 //Bit81.ID is used for information exchange(irregular use)

                    Bit81 ELM = (ConnectedCells[rcS] & CRL[1]) - CRL[2]; //CRL[2]:exclude chain of only two links(trivial solution).
                    if (ELM.IsZero())
                    {
                        continue;                                   //ELM:eliminatable cells
                    }
                    //===== X-Chain found =====
                    SolCode = 2;
                    foreach (var P in ELM.IEGetUCeNoB(pBDL, noB))
                    {
                        P.CancelB = noB;
                    }
                    string SolMsg = $"X-Chain #{(no+1)}";
                    Result = SolMsg;
                    if (SolInfoB)
                    {
                        Bit81 LKRecB = _SelectLink_XChain(LKRec, rcS, ELM, noB); //Extract related-Link
                        CRL[0] &= LKRecB; CRL[1] &= LKRecB;

                        Color Cr  = _ColorsLst[0];
                        Color Cr1 = Color.FromArgb(255, Cr.R, Cr.G, Cr.B);
                        Color Cr2 = Color.FromArgb(120, Cr.R, Cr.G, Cr.B);     //(Lightness adjustment)
                        foreach (var P in CRL[0].IEGetUCeNoB(pBDL, noB))
                        {
                            P.SetNoBBgColor(noB, AttCr, Cr2);
                        }
                        foreach (var P in CRL[1].IEGetUCeNoB(pBDL, noB))
                        {
                            P.SetNoBBgColor(noB, AttCr, Cr1);
                        }
                        pBDL[rcS].SetNoBBgColor(noB, AttCr, SolBkCr);
                        ResultLong = SolMsg;;
                    }
                    if (__SimpleAnalizerB__)
                    {
                        return(true);
                    }
                    if (!pAnMan.SnapSaveGP(true))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Exemplo n.º 2
0
        public int PrepareUGLinkMan(bool printB = false)
        {
            UGLLst        = new List <UGLink>();
            UGLink.IDnum0 = 0;

            //In UGLLst, rcb-Links is first, and cell-Links is second. This order is used in the algorithm.
            // 1)rcb-Links
            for (int no = 0; no < 9; no++)           //no:digit
            {
                Bit81 BPnoB = new Bit81(pBDL, (1 << no));
                for (int tfx = 0; tfx < 27; tfx++)   //tfx:house
                {
                    Bit81 Q = pHouseCells[tfx] & BPnoB;
                    if (Q.IsZero())
                    {
                        continue;
                    }
                    Q.no = no;
                    Q.ID = (tfx << 4) | no;                             //ID is the usage within this algorithm(UGLinkMan).
                    if (UGLLst.All(P => (P.rcBit81.no != no || P.rcBit81 != Q)))
                    {
                        UGLLst.Add(new UGLink(Q));
                    }                                                                                      //Q is unique?
//                  else{ usedLKIgnrLst.Add(Q.ID); }              //House is different but cells pattern is the same.
                }
            }

            // 2)cell-Links
            foreach (var UC in pBDL.Where(p => p.No == 0))
            {
                UGLLst.Add(new UGLink(UC));                                             // cell elements
            }
            if (printB)
            {
                UGLLst.ForEach(P => WriteLine(P.ToString("prepare")));
//             _usedLKLst_ToRCBString("### usedLKIgnrLst",usedLKIgnrLst);
            }

            _BDL_B9 = new Bit981();
            foreach (var P in pBDL.Where(p => (p.FreeB) > 0))
            {
                foreach (var no in P.FreeB.IEGet_BtoNo())
                {
                    _BDL_B9._BQ[no].BPSet(P.rc);
                }
            }
            for (int n = 0; n < 9; n++)
            {
                if (_BDL_B9._BQ[n].Count == 0)
                {
                    _BDL_B9._BQ[n] = null;
                }
            }

            return(UGLLst.Count);
        }
Exemplo n.º 3
0
        public Bit981(Bit81 P) : this()
        {
            int no = P.no;

            this._BQ[no] = P;
            if (!P.IsZero())
            {
                noBit |= (1 << no);
            }
        }
Exemplo n.º 4
0
        //Link between Cell and ALS
        public void QSearch_Cell2ALS_Link( )
        {
            if (ALSLst == null)
            {
                PrepareALSLinkMan(1);
            }
            if (LinkCeAlsLst != null)
            {
                return;
            }
            LinkCeAlsLst = new List <LinkCellALS> [81];
            if (ALSLst == null || ALSLst.Count < 2)
            {
                return;
            }

            foreach (var PA in ALSLst.Where(P => P.singly))
            {
                foreach (var no in PA.FreeB.IEGet_BtoNo())
                {
                    int   noB = (1 << no);
                    Bit81 H   = new Bit81(true);
                    foreach (var P in PA.UCellLst.Where(q => (q.FreeB & noB) > 0))
                    {
                        H &= pConnectedCells[P.rc];
                    }
                    if (H.IsZero())
                    {
                        continue;
                    }
                    foreach (var P in H.IEGetUCeNoB(pBDL, noB))
                    {
                        var Q = new LinkCellALS(P, PA, no);
                        if (LinkCeAlsLst[P.rc] == null)
                        {
                            LinkCeAlsLst[P.rc] = new List <LinkCellALS>();
                        }
                        LinkCeAlsLst[P.rc].Add(Q);
                    }
                }
            }
            for (int rc = 0; rc < 81; rc++)
            {
                if (LinkCeAlsLst[rc] != null)
                {
                    LinkCeAlsLst[rc].Sort();
                }
            }
        }
        //Coloring is an algorithm that connects the focused digit with a strong link.
        //http://csdenpe.web.fc2.com/page46.html
        public bool Color_Trap( )
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);                                         //Generate StrongLink

            for (int no = 0; no < 9; no++)
            {
                int noB = (1 << no);
                foreach (Bit81[] CRL in _Coloring(no))
                {
                    Bit81 HitB = new Bit81();
                    Bit81 ELM  = (new Bit81(pBDL, noB)) - (CRL[0] | CRL[1]);
                    foreach (var rc in ELM.IEGet_rc())
                    {
                        Bit81 HB = HouseCells[18 + rc.ToBlock()];
                        if (((ConnectedCells[rc] - HB) & CRL[0]).IsZero())
                        {
                            continue;
                        }
                        if (((ConnectedCells[rc] - HB) & CRL[1]).IsZero())
                        {
                            continue;
                        }
                        HitB.BPSet(rc);
                    }
                    if (!HitB.IsZero())
                    {
                        Color Cr  = _ColorsLst[0];
                        Color Cr1 = Cr; Cr1.A = (byte)120;              //Color.FromArgb(120,Cr.R,Cr.G,Cr.B);

                        foreach (var P in HitB.IEGet_rc().Select(p => pBDL[p]))
                        {
                            P.CancelB = noB;
                        }
                        foreach (var P in CRL[0].IEGet_rc().Select(p => pBDL[p]))
                        {
                            P.SetNoBBgColor(noB, AttCr, Cr);
                        }
                        foreach (var P in CRL[1].IEGet_rc().Select(p => pBDL[p]))
                        {
                            P.SetNoBBgColor(noB, AttCr, Cr1);
                        }

                        SolCode = 2;
                        string SolMsg = "Coloring Trap #" + (no + 1);
                        Result = SolMsg;
                        if (SolInfoB)
                        {
                            ResultLong = SolMsg;
                        }
                        if (__SimpleAnalizerB__)
                        {
                            return(true);
                        }
                        if (!pAnMan.SnapSaveGP(true))
                        {
                            return(true);
                        }
                        HitB = new Bit81();
                    }
                }
            }

            return(false);
        }
        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);
        }
        private void _KrFish_FishResult(int no, int sz, UFish Bas, UFish Cov)
        {
            int   HB = Bas.HouseB, HC = Cov.HouseC;
            Bit81 PB = Bas.BaseB81, PFin = Cov.FinB81;
            Bit81 EndoFin = Bas.EndoFin, CnaaFin = Cov.CannFin;

            string[] FishNames = { "Xwing", "SwordFish", "JellyFish", "Squirmbag", "Whale", "Leviathan" };

            PFin -= EndoFin;
            try{
                int noB = (1 << no);
                foreach (var P in PB.IEGet_rc().Select(p => pBDL[p]))
                {
                    P.SetNoBBgColor(noB, AttCr, SolBkCr);
                }
                foreach (var P in PFin.IEGet_rc().Select(p => pBDL[p]))
                {
                    P.SetNoBBgColor(noB, AttCr, SolBkCr2);
                }
                foreach (var P in EndoFin.IEGet_rc().Select(p => pBDL[p]))
                {
                    P.SetNoBBgColor(noB, AttCr, SolBkCr3);
                }
                foreach (var P in CnaaFin.IEGet_rc().Select(p => pBDL[p]))
                {
                    P.SetNoBBgColor(noB, AttCr, SolBkCr3);
                }

                string msg = "\r     Digit: " + (no + 1);
                msg += "\r   BaseSet: " + HB.HouseToString();
                msg += "\r  CoverSet: " + HC.HouseToString();;
                string msg2 = $" #{(no+1)} {HB.HouseToString().Replace(" ","")}/{HC.HouseToString().Replace(" ","")}";

                string FinmsgH = "", FinmsgT = "";
                if (PFin.Count > 0)
                {
                    FinmsgH = "Finned ";
                    string st = "";
                    foreach (var rc in PFin.IEGet_rc())
                    {
                        st += " " + rc.ToRCString();
                    }
                    msg += "\r    FinSet: " + st.ToString_SameHouseComp();
                }

                if (!EndoFin.IsZero())
                {
                    FinmsgT = " with Endo Fin";
                    string st = "";
                    foreach (var rc in EndoFin.IEGet_rc())
                    {
                        st += " " + rc.ToRCString();
                    }
                    msg += "\r  Endo Fin: " + st.ToString_SameHouseComp();
                }

                if (!CnaaFin.IsZero())
                {
                    FinmsgH = "Cannibalistic ";
                    if (PFin.Count > 0)
                    {
                        FinmsgH = "Finned Cannibalistic ";
                    }
                    string st = "";
                    foreach (var rc in CnaaFin.IEGet_rc())
                    {
                        st += " " + rc.ToRCString();
                    }
                    msg += "\r  Cannibalistic: " + st.ToString_SameHouseComp();
                }

                string Fsh = FishNames[sz - 2];
                int    bf = 0, cf = 0;
                for (int k = 0; k < 3; k++)
                {
                    if (((Bas.HouseB >> (k * 9)) & 0x1FF) > 0)
                    {
                        bf |= (1 << k);
                    }
                    if (((Cov.HouseC >> (k * 9)) & 0x1FF) > 0)
                    {
                        cf |= (1 << k);
                    }
                }
                if ((bf + cf) > 3)
                {
                    Fsh = "Franken/Mutant " + Fsh;
                }
                Fsh        = "Kraken " + FinmsgH + Fsh + FinmsgT;
                ResultLong = Fsh + msg;
                _krfMsg    = Fsh.Replace("Franken/Mutant", "F/M") + msg2;
                Result     = _krfMsg;
            }
            catch (Exception ex) {
                WriteLine(ex.Message);
                WriteLine(ex.StackTrace);
            }
        }
Exemplo n.º 8
0
        public bool ForceChain_ContradictionEx( )
        {
            GroupedLink._IDsetB = false;  //ID set for debug
            string dspOpt = GNPXApp000.GMthdOption["ForceLx"];
            string st0 = "", st2 = "";

            Prepare();
            pSprLKsMan.PrepareSuperLinkMan(AllF: true);
            Bit81[] GLC = new Bit81[9];
            for (int k = 0; k < 9; k++)
            {
                GLC[k] = new Bit81();
            }

            foreach (var P0 in pBDL.Where(p => p.No == 0))
            {
                foreach (var no in P0.FreeB.IEGet_BtoNo())
                {
                    int        noB  = (1 << no);
                    USuperLink USLK = pSprLKsMan.get_L2SprLKEx(P0.rc, no, FullSearchB: false, DevelopB: false);
                    if (USLK != null)
                    {
                        Bit81 sContradict = new Bit81();

                        for (int k = 0; k < 9; k++)
                        {
                            sContradict = USLK.Qtrue[k] & USLK.Qfalse[k];
                            if (sContradict.IsZero())
                            {
                                continue;
                            }

                            foreach (var Q in sContradict.IEGet_rc().Select(rc => pBDL[rc]))
                            {
                                P0.CancelB |= noB;
                                P0.SetCellBgColor(Colors.LightGreen);
                                int E = P0.FreeB.DifSet(P0.CancelB);
                                SolCode = (E.BitCount() == 1)? 1: 2;

                                if (SolInfoB)
                                {
                                    if (dspOpt != "ForceL2")
                                    {
                                        Q.SetNoBBgColor(Q.FreeB, Colors.Green, Colors.Yellow);
                                    }
                                    P0.SetNoBColorRev(noB, Colors.Red);
                                    if (E.BitCount() == 1)
                                    {
                                        P0.SetNoBColor(E, Colors.Red);
                                    }
                                    GLC[no].BPSet(P0.rc);
                                    st0    = $"ForceChain_Contradiction r{(P0.r+1)}c{(P0.c+1)}/#{(no+1)} is false";
                                    Result = ResultLong = st0;

                                    string stX = pSprLKsMan._GenMessage2true(USLK, Q, k);
                                    stX += "\r" + pSprLKsMan._GenMessage2false(USLK, Q, k);

                                    if (st2 != "")
                                    {
                                        st2 += "\r";
                                    }
                                    st2   += (st0 + "\r" + stX);
                                    st2    = st2.Trim();
                                    extRes = st2;
                                    if (dspOpt == "ForceL0")
                                    {
                                        if (__SimpleAnalizerB__)
                                        {
                                            return(true);
                                        }
                                        if (!pAnMan.SnapSaveGP(false))
                                        {
                                            return(true);
                                        }
                                        st2 = "";
                                    }
                                }
                                goto LNextSearch;      //One contradictory cell is enough
                            }
                        }
                    }

LNextSearch:
                    if (SolInfoB && dspOpt == "ForceL1" && st2 != "")
                    {
                        Result = ResultLong = $"ForceChain_Contradiction {P0.rc.ToRCString()}";
                        extRes = st2;
                        if (__SimpleAnalizerB__)
                        {
                            return(true);
                        }
                        if (!pAnMan.SnapSaveGP(false))
                        {
                            return(true);
                        }
                        st2 = "";
                    }
                }
            }
            if (SolInfoB && dspOpt == "ForceL2" && st2 != "")
            {
                Result = ResultLong = "ForceChain_Contradiction";
                extRes = st2;
                if (__SimpleAnalizerB__)
                {
                    return(true);
                }
                if (!pAnMan.SnapSaveGP(false))
                {
                    return(true);
                }
            }
            _developDisp2Ex(GLC);                                                       //37
            return(SolCode > 0);
        }
        public bool ExtFishSub(int sz, int no, int FMSize, int BaseSel, int CoverSel, bool FinnedF, bool _Fdef = true)
        {
            int  noB     = (1 << no);
            bool extFlag = (sz >= 3 && ((BaseSel | CoverSel).BitCount() > 18));

            if (_Fdef)
            {
                FMan = new FishMan(this, FMSize, no, sz, extFlag);
            }

            foreach (var Bas in FMan.IEGet_BaseSet(BaseSel, FinnedF:FinnedF))     //select BaseSet
            {
                if (pAnMan.CheckTimeOut())
                {
                    return(false);
                }

                foreach (var Cov in FMan.IEGet_CoverSet(Bas, CoverSel, FinnedF))   //select CoverSet
                {
                    Bit81 FinB81 = Cov.FinB81;

                    Bit81 ELM      = null;
                    var   FinZeroB = FinB81.IsZero();
                    if (!FinnedF && FinZeroB)    //===== no Fin =====
                    {
                        if (!FinnedF && (ELM = Cov.CoverB81 - Bas.BaseB81).Count > 0)
                        {
                            foreach (var P in ELM.IEGetUCeNoB(pBDL, noB))
                            {
                                P.CancelB = noB; SolCode = 2;
                            }
                            if (SolCode > 0)       //solved!(
                            {
                                if (SolInfoB)
                                {
                                    _Fish_FishResult(no, sz, Bas, Cov, (FMSize == 27)); //FMSize 18:regular 27:Franken/Mutant
                                }
                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(true))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                    else if (FinnedF && !FinZeroB)      //===== Finned =====
                    {
                        Bit81 Ecand = Cov.CoverB81 - Bas.BaseB81;
                        ELM = new Bit81();
                        foreach (var P in Ecand.IEGetUCeNoB(pBDL, noB))
                        {
                            if ((FinB81 - ConnectedCells[P.rc]).Count == 0)
                            {
                                ELM.BPSet(P.rc);
                            }
                        }
                        if (ELM.Count > 0)     //there are cells/digits can be excluded
                        {
                            foreach (var P in ELM.IEGet_rc().Select(p => pBDL[p]))
                            {
                                P.CancelB = noB; SolCode = 2;
                            }
                            if (SolCode > 0)   //solved!
                            {
                                if (SolInfoB)
                                {
                                    _Fish_FishResult(no, sz, Bas, Cov, (FMSize == 27)); //FMSize 18:regular 27:Franken/Mutant
                                }
                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(true))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                    continue;
                }
            }
            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);
            }
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
0
        public IEnumerable <GroupedLink> IEGet_SuperLink(GroupedLink GLKpre)
        {
            int  SWCtrl = GLKpre.type;
            bool ALSpre = GLKpre is ALSLink;

            if (GLKpre.UGCellsB.Count == 1)
            {
                UCell            U    = GLKpre.UGCellsB[0];
                List <UCellLink> Plst = CeLKMan.CeLK81[U.rc];
                if (Plst != null)
                {
                    foreach (var LK in Plst)
                    {
                        if (ALSpre && LK.type != W)
                        {
                            continue;
                        }
                        GroupedLink GLK = new GroupedLink(LK);
                        if (Check_SuperLinkSequence(GLKpre, GLK))
                        {
                            yield return(GLK);
                        }
                    }
                }
            }

            if (GNPXApp000.GMthdOption["GroupedCells"] == "1")
            {
                foreach (var GP in GLKMan.GrpCeLKLst)
                {
                    if (ALSpre && GP.type != W)
                    {
                        continue;
                    }
                    if (!GLKpre.UGCellsB.EqualsRC(GP.UGCellsA))
                    {
                        continue;
                    }
                    if (GLKpre.no2 != GP.no)
                    {
                        continue;
                    }
                    if (Check_SuperLinkSequence(GLKpre, GP))
                    {
                        yield return(GP);
                    }
                }
            }

            if (GNPXApp000.GMthdOption["ALS"] == "1" && ALSMan.AlsInnerLink != null)
            {
                if (GLKpre.type == W)
                {
                    foreach (var GP in ALSMan.AlsInnerLink.Where(p => (p.ALSbase.Level == 1)))
                    {
                        if (GLKpre.no2 != GP.no)
                        {
                            continue;
                        }
                        if (GLKpre.UGCellsB.Equals(GP.UGCellsA))
                        {
                            yield return(GP);
                        }
                    }
                }
            }

            if (ALSpre)
            {
                ALSLink ALK   = GLKpre as ALSLink;
                int     noB   = 1 << ALK.no2;
                Bit81   BPnoB = new Bit81(pBDL, noB);

                Bit81 BP = BPnoB & ALK.UGCellsB.B81;
                //      ALK.UGCellsB.ForEach(P=>{ if((P.FreeB&noB)>0) BP.BPSet(P.rc); });

                Bit81 UsedCs = GLKpre.UsedCs;
                for (int tfx = 0; tfx < 27; tfx++)
                {
                    Bit81 HS = BPnoB & pHouseCells[tfx];
                    if (!(BP - HS).IsZero())
                    {
                        continue;
                    }
                    if ((HS - BP).IsZero())
                    {
                        continue;
                    }

                    Bit81 NxtBP = HS - BP - UsedCs;
                    if (NxtBP.IsZero())
                    {
                        continue;
                    }

//C                        WriteLine("\n tfx:"+tfx );
//C                        WriteLine( "   BP:"+BP );
//C                        WriteLine( "   HS:"+HS );
//C                        WriteLine( "HS-BP:"+(HS-BP) );
//C                        WriteLine( "NxtBP:"+NxtBP );

                    List <UCell> NxtCs = NxtBP.ToList().ConvertAll(rc => pBDL[rc]);
                    for (int k = 1; k < (1 << NxtCs.Count); k++)
                    {
                        UGrCells NxtGrpdCs = new UGrCells(tfx, ALK.no2);
                        int      kb        = k;
                        for (int n = 0; n < NxtCs.Count; n++)
                        {
                            if ((kb & 1) > 0)
                            {
                                NxtGrpdCs.Add(new UGrCells(NxtCs[n], ALK.no2));
                            }
                            kb >>= 1;
                        }
                        GroupedLink GP = new GroupedLink(GLKpre.UGCellsB, NxtGrpdCs, tfx, W);
//C                        WriteLine( GP );
                        yield return(GP);
                    }
                }
            }
            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 = new Bit81(ELM2);
                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);
        }
        }                                        //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);
        }