Ejemplo n.º 1
0
 private void Prepare()
 {
     if (pAnMan.GStage != GStageMemo)
     {
         GStageMemo = pAnMan.GStage;
         ALSMan.Initialize();
         ALSMan.PrepareALSLinkMan(1);
     }
 }
Ejemplo n.º 2
0
        public bool ALS_DeathBlossomExt()
        {
            Prepare();
            if (ALSMan.ALSLst == null || ALSMan.ALSLst.Count <= 2)
            {
                return(false);
            }
            ALSMan.QSearch_Cell2ALS_Link();

            for (int sz = 2; sz <= 4; sz++)      //Size 5 and over ALS DeathBlossom was not found?
            {
                if (_ALS_DeathBlossomSubEx(sz, stmLinked:true))
                {
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 3
0
        //ALS Chain is an algorithm that connects ALS into a loop in RCC.
        // http://csdenpe.web.fc2.com/page52.html
        public bool ALS_Chain()
        {
            Prepare();
            if (ALSMan.ALSLst == null || ALSMan.ALSLst.Count <= 3)
            {
                return(false);
            }
            ALSMan.QSearch_ALS2ALS_Link(true);                  //T:doubly+singly (F:only singly)

            for (int szCtrl = 3; szCtrl <= 12; szCtrl++)        //Search from small size ALS-Chain
            {
                if (pAnMan.CheckTimeOut())
                {
                    return(false);
                }
                var SolStack = new Stack <UALSPair>();
                foreach (var ALSHead in ALSMan.ALSLst.Where(p => p.ConnLst != null && !p.LimitF))
                {
                    if (!ALSHead.singly)
                    {
                        continue;
                    }
                    bool limitF = false;
                    foreach (var LK0 in ALSHead.ConnLst)
                    {
                        SolStack.Push(LK0);
                        LK0.rcUsed = LK0.ALSpre.B81 | LK0.ALSnxt.B81;
                        int szCtrlX = szCtrl - LK0.ALSpre.Size - LK0.ALSnxt.Size;
                        _Search_ALSChain(LK0, LK0, SolStack, szCtrlX, ref limitF);     //First Recursive Search
                        if (SolCode > 0)
                        {
                            return(true);
                        }
                        SolStack.Pop();
                    }
                    if (!limitF)
                    {
                        ALSHead.LimitF = true;
                    }
                                                     //When the solution is within the size limit, do not search by the next size
                }
            }
            return(false);
        }
Ejemplo n.º 4
0
        private bool _ALSXZsub(int sz)
        {
            if (ALSMan.ALSLst.Count < 2)
            {
                return(false);
            }

            var cmb = new Combination(ALSMan.ALSLst.Count, 2);
            int nxt = 99;

            while (cmb.Successor(nxt))                          //Select two ALSs
            {
                UALS UA = ALSMan.ALSLst[cmb.Index[0]];
                nxt = 0; if (!UA.singly || UA.Size == 1 || UA.Size > (sz - 2))
                {
                    continue;
                }

                UALS UB = ALSMan.ALSLst[cmb.Index[1]];
                nxt = 1; if (!UB.singly || UB.Size == 1 || (UA.Size + UB.Size) != sz)
                {
                    continue;
                }

                int RCC = ALSMan.Get_AlsAlsRcc(UA, UB);          //Common numbers, House contact, Without overlap
                if (RCC == 0)
                {
                    continue;
                }

                if (RCC.BitCount() == 1)                          //===== Singly Linked =====
                {
                    int EnoB = (UA.FreeB & UB.FreeB).DifSet(RCC); //Exclude candidate digit
                    if (EnoB > 0 && _ALSXZ_SinglyLinked(UA, UB, RCC, EnoB))
                    {
                        SolCode = 2;
                        ALSXZ_SolResult(RCC, UA, UB);

                        if (__SimpleAnalizerB__)
                        {
                            return(true);
                        }
                        if (!pAnMan.SnapSaveGP(true))
                        {
                            return(true);
                        }
                    }
                }
                else if (RCC.BitCount() == 2)    //===== Doubly Linked =====
                {
                    if (_ALSXZ_DoublyLinked(UA, UB, RCC))
                    {
                        SolCode = 2;
                        ALSXZ_SolResult(RCC, UA, UB);

                        if (__SimpleAnalizerB__)
                        {
                            return(true);
                        }
                        if (!pAnMan.SnapSaveGP(true))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 5
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 bool _ALSXYWingSub(int szT)
        {
            //(ALS sorted by size)
            foreach (var UC in ALSMan.ALSLst.Where(p => p.Size <= szT - 2))
            {
                if (!UC.singly)
                {
                    continue;
                }
                int szS = szT - UC.Size;

                UALS UA, UB, UApre = null;
                int  nxt = 0, RccAC = -1, RccBC = -1;
                var  cmb = new Combination(ALSMan.ALSLst.Count, 2);
                while (cmb.Successor(nxt))
                {
                    nxt = 0;
                    UA  = ALSMan.ALSLst[cmb.Index[0]];
                    if (!UA.singly || UA == UC || UA.Size > szS - 1)
                    {
                        continue;
                    }
                    if (UA != UApre)
                    {
                        RccAC = ALSMan.Get_AlsAlsRcc(UA, UC);    //RCC
                        if (RccAC.BitCount() != 1)
                        {
                            continue;
                        }
                        UApre = UA;
                    }

                    UB = ALSMan.ALSLst[cmb.Index[1]];
                    if (!UB.singly || UB.Size > (szS - UA.Size))
                    {
                        continue;                                      //Skip using "Sort by size"
                    }
                    nxt = 1;
                    if (UB == UC || UB.Size != (szS - UA.Size))
                    {
                        continue;
                    }
                    if (!(UA.B81 & UB.B81).IsZero())
                    {
                        continue;                               //Overlap
                    }
                    RccBC = ALSMan.Get_AlsAlsRcc(UB, UC);       //RCC
                    if (RccBC.BitCount() != 1)
                    {
                        continue;
                    }
                    if (RccAC == RccBC)
                    {
                        continue;
                    }

                    int EFrB = (UA.FreeB & UB.FreeB).DifSet(RccAC | RccBC);
                    if (EFrB == 0)
                    {
                        continue;
                    }
                    foreach (var no in EFrB.IEGet_BtoNo())
                    {
                        int   noB = (1 << no);
                        Bit81 UE  = new Bit81();
                        foreach (var P in UA.UCellLst.Where(p => (p.FreeB & noB) > 0))
                        {
                            UE.BPSet(P.rc);
                        }
                        foreach (var P in UB.UCellLst.Where(p => (p.FreeB & noB) > 0))
                        {
                            UE.BPSet(P.rc);
                        }

                        Bit81 TBD = (new Bit81(pBDL, noB)) - (UA.B81 | UB.B81 | UC.B81);
                        foreach (var rc in TBD.IEGet_rc())
                        {
                            if (!(UE - ConnectedCells[rc]).IsZero())
                            {
                                continue;
                            }
                            pBDL[rc].CancelB = noB; SolCode = 2;
                        }

                        if (SolCode > 0) //===== ALS XY-Wing found =====
                        {
                            ALSXYWing_SolResult(UA, UB, UC, RccAC, RccBC);
                            if (__SimpleAnalizerB__)
                            {
                                return(true);
                            }
                            if (!pAnMan.SnapSaveGP(true))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }