Beispiel #1
0
        private bool _ALSXZ_SinglyLinked(UALS UA, UALS UB, int RCC, int EnoB)       // *=*=* SinglyLinked subroutine *=*=*
        {
            bool solF = false;

            foreach (var no in EnoB.IEGet_BtoNo())
            {
                int EnoBx = 1 << no;

                Bit81 UEz = new Bit81();  //Covered cells
                foreach (var P in UA.UCellLst.Where(p => (p.FreeB & EnoBx) > 0))
                {
                    UEz.BPSet(P.rc);
                }
                foreach (var P in UB.UCellLst.Where(p => (p.FreeB & EnoBx) > 0))
                {
                    UEz.BPSet(P.rc);
                }

                Bit81 Elm = (new Bit81(pBDL, EnoBx)) - (UA.B81 | UB.B81); //Scan Cells

                foreach (var rc in Elm.IEGet_rc())
                {
                    if ((UEz - ConnectedCells[rc]).IsZero())
                    {
                        pBDL[rc].CancelB |= EnoBx; solF = true;
                    }
                }
            }
            return(solF);
        }
Beispiel #2
0
        public bool EndoFinnedFMFish_sub(int sz, int no, int FMSize, bool FinnedF, bool EndoF = false, bool CannF = false)
        {
            int     noB = (1 << no);
            int     BaseSel = 0x7FFFFFF, CoverSel = 0x7FFFFFF;
            FishMan FMan = new FishMan(this, FMSize, no, sz, (sz >= 3));

            foreach (var Bas in FMan.IEGet_BaseSet(BaseSel, FinnedF:FinnedF, EndoFlg:EndoF)) //BaseSet

            {
                foreach (var Cov in FMan.IEGet_CoverSet(Bas, CoverSel, CannF))                //CoverSet
                {
                    if (pAnMan.CheckTimeOut())
                    {
                        return(false);
                    }
                    Bit81 FinB81 = Cov.FinB81 | Bas.EndoFin;
                    Bit81 E      = Cov.CoverB81 - Bas.BaseB81;
                    Bit81 ELM    = new Bit81();

                    //see latest viewpoint
                    foreach (var rc in E.IEGet_rc())
                    {
                        if ((FinB81 - ConnectedCells[rc]).Count == 0)
                        {
                            ELM.BPSet(rc);
                        }
                    }
                    if (ELM.Count > 0)
                    {
                        foreach (var P in ELM.IEGetUCeNoB(pBDL, noB))
                        {
                            P.CancelB = noB; SolCode = 2;
                        }
                        if (SolCode > 0)
                        {
                            if (SolInfoB)
                            {
                                _Fish_FishResult(no, sz, Bas, Cov, (FMSize == 27)); //27:Franken/Mutant
                            }
                            //WriteLine(ResultLong);
                            if (__SimpleAnalizerB__)
                            {
                                return(true);
                            }
                            if (!pAnMan.SnapSaveGP(true))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }
            public Bit81F(Bit81 rcB, int ID) : base(rcB)
            {
                int rr = 0, cc = 0, bb = 0;

                this.ID = ID;
                foreach (var rc in rcB.IEGet_rc())
                {
                    rr |= (1 << (rc / 9)); cc |= (1 << (rc % 9)); bb |= (1 << (rc / 27 * 3 + (rc % 9) / 3));
                }
                rcbB = (rr) | (cc << 9) | (bb << 18);                  //Bit expression of block/column/block from rcB(0-80)
                //WriteLine( rcB.ToRCString()+" "+rcbB.ToBitString27() );
            }
Beispiel #4
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;
        }
Beispiel #5
0
        private bool _CheckSolution_ALSChain(UALSPair LK0, UALSPair LKn, Bit81 rcUsed, Stack <UALSPair> SolStack)
        {
            int ElmBH = LK0.ALSpre.FreeB.BitReset(LK0.nRCC);    //non-RCC digit of First ALS
            int ElmBT = LKn.ALSnxt.FreeB.BitReset(LKn.nRCC);    //non-RCC digit of Last ALS
            int ElmB  = ElmBH & ElmBT;

            if (ElmB == 0)
            {
                return(false);                                  //if no common digits then Failure.
            }
            foreach (int Eno in ElmB.IEGet_BtoNo())             //Eno is one of common digits
            {
                int   EnoB = (1 << Eno);
                Bit81 Ez   = new Bit81();                       //Negative cell candidate
                foreach (var P in LK0.ALSpre.UCellLst.Where(p => (p.FreeB & EnoB) > 0))
                {
                    Ez.BPSet(P.rc);
                }
                foreach (var P in LKn.ALSnxt.UCellLst.Where(p => (p.FreeB & EnoB) > 0))
                {
                    Ez.BPSet(P.rc);
                }

                Bit81 TBD = (new Bit81(pBDL, EnoB)) - rcUsed;        //Exclude cells in the chain
                foreach (var rc in TBD.IEGet_rc())
                {
                    if ((Ez - ConnectedCells[rc]).IsZero())
                    {
                        pBDL[rc].CancelB |= EnoB; SolCode = 2;
                    }                                                                            //found solution
                }
            }

            if (SolCode > 0)
            {
                _SolResult_ALSChain(SolStack);

                if (__SimpleAnalizerB__)
                {
                    return(true);
                }
                if (!pAnMan.SnapSaveGP(true))
                {
                    return(true);
                }
            }
            return(false);
        }
        //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);
            }
        }
Beispiel #9
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);
        }
Beispiel #10
0
        private bool _ALSXZ_DoublyLinked(UALS UA, UALS UB, int RCC)                 // *=*=* DoublyLinked subroutine *=*=*
        //----- RCC -----
        {
            Bit81 UEz  = new Bit81(); //Covered cells
            bool  solF = false;

            foreach (int no in RCC.IEGet_BtoNo())
            {
                int noB = 1 << no;
                UEz.Clear();
                foreach (var P in UA.UCellLst.Where(p => (p.FreeB & noB) > 0))
                {
                    UEz.BPSet(P.rc);
                }
                foreach (var P in UB.UCellLst.Where(p => (p.FreeB & noB) > 0))
                {
                    UEz.BPSet(P.rc);
                }

                Bit81 Elm = (new Bit81(pBDL, noB)) - (UA.B81 | UB.B81);    //Scan Cells
                foreach (var rc in Elm.IEGet_rc())
                {
                    if ((UEz - ConnectedCells[rc]).IsZero())
                    {
                        pBDL[rc].CancelB |= noB; solF = true;
                    }
                }
            }

            //----- ALS element digit other than RCC -----
            int nRCC = UA.FreeB.DifSet(RCC);

            foreach (int no in nRCC.IEGet_BtoNo())
            {
                int noB = 1 << no;
                UEz.Clear();
                foreach (var P in UA.UCellLst.Where(p => (p.FreeB & noB) > 0))
                {
                    UEz.BPSet(P.rc);
                }
                Bit81 Elm = (new Bit81(pBDL, noB)) - (UA.B81 | UB.B81);   //Scan Cells
                foreach (var rc in Elm.IEGet_rc())
                {
                    if ((UEz - ConnectedCells[rc]).IsZero())
                    {
                        pBDL[rc].CancelB |= noB; solF = true;
                    }
                }
            }
            nRCC = UB.FreeB.DifSet(RCC);
            foreach (int no in nRCC.IEGet_BtoNo())
            {
                int noB = 1 << no;
                UEz.Clear();
                foreach (var P in UB.UCellLst.Where(p => (p.FreeB & noB) > 0))
                {
                    UEz.BPSet(P.rc);
                }
                Bit81 Elm = (new Bit81(pBDL, noB)) - (UA.B81 | UB.B81);    //Scan Cells
                foreach (var rc in Elm.IEGet_rc())
                {
                    if ((UEz - ConnectedCells[rc]).IsZero())
                    {
                        pBDL[rc].CancelB |= noB; solF = true;
                    }
                }
            }
            return(solF);
        }
        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);
            }
        }
        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);
        }
Beispiel #13
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);
        }
        }                                        //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);
        }
        //=================== MultiColoring ==================================
        public bool MultiColor_Type1( )
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);                //Generate StrongLink

            for (int no = 0; no < 9; no++)
            {
                int            noB  = (1 << no);
                List <Bit81[]> MCRL = _Coloring(no).ToList();
                if (MCRL == null || MCRL.Count < 2)
                {
                    continue;
                }
                var cmb = new Combination(MCRL.Count, 2);
                while (cmb.Successor())
                {
                    Bit81[] CRLa = MCRL[cmb.Index[0]];
                    Bit81[] CRLb = MCRL[cmb.Index[1]];
                    for (int na = 0; na < 2; na++)
                    {
                        Bit81 HCRLa = new Bit81();
                        foreach (var rc in CRLa[na].IEGet_rc())
                        {
                            HCRLa |= ConnectedCells[rc];
                        }
                        for (int nb = 0; nb < 2; nb++)
                        {
                            if ((HCRLa & CRLb[nb]).IsZero())
                            {
                                continue;
                            }

                            Bit81 BD0    = new Bit81(pBDL, noB);
                            Bit81 ELMtry = BD0 - (CRLa[na] | CRLb[nb] | CRLa[1 - na] | CRLb[1 - nb]);
                            if (ELMtry.Count == 0)
                            {
                                continue;
                            }

                            bool  solF = false;
                            Bit81 ELM  = new Bit81();
                            foreach (var rc in ELMtry.IEGet_rc())
                            {
                                if (!ConnectedCells[rc].IsHit(CRLa[1 - na]))
                                {
                                    continue;
                                }
                                if (!ConnectedCells[rc].IsHit(CRLb[1 - nb]))
                                {
                                    continue;
                                }
                                pBDL[rc].CancelB = noB; ELM.BPSet(rc); solF = true;
                            }
                            if (solF)
                            {
                                Color CrA = _ColorsLst[0];
                                foreach (var P in ELM.IEGet_rc().Select(p => pBDL[p]))
                                {
                                    P.SetNoBBgColor(noB, AttCr, CrA);
                                }
                                for (int k = 0; k < 2; k++)
                                {
                                    Bit81[] CRLX = MCRL[cmb.Index[k]];
                                    Color   Cr1  = _ColorsLst[k];
                                    Color   Cr2  = Cr1; Cr2.A = (byte)120;
                                    foreach (var P in CRLX[1 - k].IEGet_rc().Select(p => pBDL[p]))
                                    {
                                        P.SetNoBBgColor(noB, AttCr, Cr1);
                                    }
                                    foreach (var P in CRLX[k].IEGet_rc().Select(p => pBDL[p]))
                                    {
                                        P.SetNoBBgColor(noB, AttCr, Cr2);
                                    }
                                }

                                SolCode = 2;
                                string SolMsg = "MultiColoring Type1 #" + (no + 1);
                                Result = SolMsg;
                                if (SolInfoB)
                                {
                                    ResultLong = SolMsg;
                                }
                                if (__SimpleAnalizerB__)
                                {
                                    return(true);
                                }
                                if (!pAnMan.SnapSaveGP(true))
                                {
                                    return(true);
                                }
                                solF = false;
                            }
                        }
                    }
                }
            }
            return(false);
        }
        public bool Color_Wrap( )
        {
            Prepare();
            CeLKMan.PrepareCellLink(1);                //Generate StrongLink

            for (int no = 0; no < 9; no++)
            {
                int noB = (1 << no);
                foreach (Bit81[] CRL in _Coloring(no))
                {
                    Bit81 BD0 = new Bit81(pBDL, noB);
                    Bit81 ELM = BD0 - (CRL[0] | CRL[1]);
                    if (ELM.Count == 0)
                    {
                        continue;
                    }

                    for (int k = 0; k < 2; k++)
                    {
                        for (int dr = 0; dr < 27; dr++)
                        {
                            if ((CRL[k] & HouseCells[dr]).Count < 2)
                            {
                                continue;
                            }
                            Color CrA = _ColorsLst[1];
                            Color Cr  = _ColorsLst[0];
                            Color Cr1 = Cr;
                            Color Cr2 = Color.FromArgb(120, Cr.R, Cr.G, Cr.B);
                            foreach (var P in ELM.IEGet_rc().Select(p => pBDL[p]))
                            {
                                P.SetNoBBgColor(noB, AttCr, CrA);
                            }
                            foreach (var P in CRL[1 - k].IEGet_rc().Select(p => pBDL[p]))
                            {
                                P.SetNoBBgColor(noB, AttCr, Cr1);
                            }
                            foreach (var P in CRL[k].IEGet_rc().Select(p => pBDL[p]))
                            {
                                P.SetCellBgColor(Cr2); P.CancelB = noB;
                            }

                            SolCode = 2;
                            string SolMsg = "Coloring Wrap #" + (no + 1);
                            Result = SolMsg;
                            if (SolInfoB)
                            {
                                ResultLong = SolMsg;
                            }
                            if (__SimpleAnalizerB__)
                            {
                                return(true);
                            }
                            if (!pAnMan.SnapSaveGP(true))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }
        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);
        }