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
        private void _SolResult_ALSChain(Stack <UALSPair> SolStack)
        {
            string st = "ALS Chain";

            if (SolInfoB)
            {
                int   nc = 0, noB;
                Color cr;
                var   SSrev = SolStack.ToList();
                SSrev.Reverse();

                foreach (var LKA in SSrev)
                {
                    noB = (1 << LKA.nRCC);
                    UALS UA = LKA.ALSpre;
                    cr = _ColorsLst[nc++];
                    UA.UCellLst.ForEach(P => P.SetNoBBgColor(noB, AttCr, cr));
                    st += $"\r ALS {nc}: {UA.ToStringRCN()} -> #{(LKA.nRCC+1)}";
                }
                var LKB = SSrev.Last();
                noB = (1 << LKB.nRCC);
                cr  = _ColorsLst[nc];
                LKB.ALSnxt.UCellLst.ForEach(P => P.SetNoBBgColor(noB, AttCr, cr));
                st        += $"\r ALS {(nc+1)}: {LKB.ALSnxt.ToStringRCN()}";
                ResultLong = st;
            }
            Result = "ALS Chain";
        }
Beispiel #3
0
        private void SuDoQueEx_SolResult(UALS ISPB, UALS ISPR)
        {
            Result = "SueDeCoq";

            if (SolInfoB)
            {
                ISPB.UCellLst.ForEach(P => P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr));
                ISPR.UCellLst.ForEach(P => P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr));

                string ptmp = "";
                ISPB.UCellLst.ForEach(p => { ptmp += $" {p.rc.ToRCString()}"; });

                string po = "\r Cells";
                if (ISPB.Level == 1)
                {
                    po += "(block)  ";
                }
                else
                {
                    po += $"-{ISPB.Level}(block)";
                }
                po += $": {ISPB.ToStringRCN()}";

                po        += "\r Cells" + ((ISPR.Level == 1)? "": "-2");
                po        += ((ISPR.tfx < 9)? "(row)":"(col)");
                po        += ((ISPR.Level == 1)? "    ": "  ");
                po        += ": " + ISPR.ToStringRCN();
                ResultLong = "SueDeCoq" + po;
            }
        }
Beispiel #4
0
 public ALSLink(UALS ALSbase, UGrCells UGCellsA, UGrCells UGCellsB, int tfx)
 {
     this.ALSbase  = ALSbase;
     this.UGCellsA = UGCellsA;
     this.UGCellsB = UGCellsB;
     this.tfx      = tfx;
     this.type     = S;
 }
Beispiel #5
0
        //Link by ALS-ALS RCC
        public void QSearch_ALS2ALS_Link(bool doubly)
        {
            if (ALSLst == null)
            {
                PrepareALSLinkMan(1);
            }

            if (ALS2ALS_Link)
            {
                return;
            }
            ALS2ALS_Link = true;

            var cmb = new Combination(ALSLst.Count, 2);

            while (cmb.Successor())
            {
                UALS UA = ALSLst[cmb.Index[0]];
                UALS UB = ALSLst[cmb.Index[1]];

                int RCC = Get_AlsAlsRcc(UA, UB);
                if (RCC == 0)
                {
                    continue;
                }
                if (!doubly && RCC.BitCount() != 1)
                {
                    continue;
                }

                if (UA.ConnLst == null)
                {
                    UA.ConnLst = new List <UALSPair>();
                }
                if (UB.ConnLst == null)
                {
                    UB.ConnLst = new List <UALSPair>();
                }
                foreach (var no in RCC.IEGet_BtoNo())
                {
                    UALSPair LKX = new UALSPair(UA, UB, RCC, no);
                    if (!UA.ConnLst.Contains(LKX))
                    {
                        UA.ConnLst.Add(LKX);
                    }
                    LKX = new UALSPair(UB, UA, RCC, no);
                    if (!UB.ConnLst.Contains(LKX))
                    {
                        UB.ConnLst.Add(LKX);
                    }
                }
            }
        }
Beispiel #6
0
        //RCC
        public int  Get_AlsAlsRcc(UALS UA, UALS UB)
        {
            if ((UA.FreeB & UB.FreeB) == 0)
            {
                return(0);                                 //no common digit
            }
            if (!(UA.B81 & UB.B81).IsZero())
            {
                return(0);                                 //overlaps 
            }
            if ((UA.rcbFilter & UB.B81).IsZero())
            {
                return(0);                                 //no contact
            }
            int RCC = 0, Dir = UA.rcbDir & UB.rcbDir;

            //[definition] rcbDir |= ( (1<<(P.b+18)) | (1<<(P.c+9)) | (1<<(P.r)) );
            foreach (int tfx in Dir.IEGet_BtoNo(27))
            {
                Bit81 ComH = pHouseCells[tfx];
                int   FrAi = 0, FrAo = 0, FrBi = 0, FrBo = 0;
                UA.UCellLst.ForEach(P => {
                    if (ComH.IsHit(P.rc))
                    {
                        FrAi |= P.FreeB;
                    }
                    else
                    {
                        FrAo |= P.FreeB;
                    }
                });
                UB.UCellLst.ForEach(P => {
                    if (ComH.IsHit(P.rc))
                    {
                        FrBi |= P.FreeB;
                    }
                    else
                    {
                        FrBo |= P.FreeB;
                    }
                });
                RCC |= (FrAi.DifSet(FrAo)) & (FrBi.DifSet(FrBo));    //RCC
            }
            return(RCC);
        }
        public int CompareTo(object obj)
        {
            UALS UB = obj as UALS;

            if (this.Level != UB.Level)
            {
                return(this.Level - UB.Level);
            }
            if (this.Size != UB.Size)
            {
                return(this.Size - UB.Size);
            }
            if (this.tfx != UB.tfx)
            {
                return(this.tfx - UB.tfx);
            }
            return(this.ID - UB.ID);
        }
        private void ALSXYWing_SolResult(UALS UA, UALS UB, UALS UC, int RccAC, int RccBC)
        {
            string st = "ALS XY-Wing ";

            if (SolInfoB)
            {
                UA.UCellLst.ForEach(P => P.SetNoBBgColor(RccAC, AttCr, SolBkCr));
                UB.UCellLst.ForEach(P => P.SetNoBBgColor(RccBC, AttCr, SolBkCr2));
                UC.UCellLst.ForEach(P => P.SetNoBBgColor(RccAC | RccBC, AttCr, SolBkCr3));

                st        += "\r ALS A: " + UA.ToStringRCN();
                st        += "\r ALS B: " + UB.ToStringRCN();
                st        += "\r ALS C: " + UC.ToStringRCN();
                st        += "\r RCC AC: #" + RccAC.ToBitStringN(9);
                st        += "\r RCC BC: #" + RccBC.ToBitStringN(9);
                ResultLong = st;
            }
            Result = "ALS XY-Wing";
        }
Beispiel #9
0
        private void _SetGroupedLink(UALS P, UGrCells GS, UGrCells GD, int tfx)
        {
            ALSLink ALSLK = new ALSLink(P, GS, GD, tfx);

            if (AlsInnerLink == null)
            {
                AlsInnerLink = new List <ALSLink>();
            }
            if (AlsInnerLink.Count > 0)
            {
                int ix = AlsInnerLink.FindIndex(Q => (Q.Equals(ALSLK)));
                if (ix >= 0)
                {
                    return;
                }
            }
            AlsInnerLink.Add(ALSLK);

            //WriteLine( $"ALSLink {GS.GCToString()} -> tfx:{tfx} {GD.GCToString()}" );
        }
Beispiel #10
0
        private bool _Search_ALSChain(UALSPair LK0, UALSPair LKpre, Stack <UALSPair> SolStack, int szCtrl, ref bool limitF)
        {
            int nRccPre = LKpre.nRCC;

            foreach (var LKnxt in LKpre.ALSnxt.ConnLst.Where(p => (p.nRCC != nRccPre)))
            {
                UALS UAnxt = LKnxt.ALSnxt;                            //Next connected ALS
                if (!UAnxt.singly)
                {
                    continue;
                }
                int szCtrlX = szCtrl - UAnxt.Size;                    //ChainsSize:Accumulation of ALS size
                if (szCtrlX < 0)
                {
                    limitF = true; return(false);
                }                                                   //Upper limit of ChainsSize has been exceeded
                if (!(LKpre.rcUsed & UAnxt.B81).IsZero())
                {
                    continue;             //Stop if the next node has been searched
                }
                {                         //===== Extend the link and try ahead =====
                    SolStack.Push(LKnxt); //Push the next Link onto the stack

                    Bit81 rcUsedNxt = LKpre.rcUsed | UAnxt.B81;
                    if (_CheckSolution_ALSChain(LK0, LKnxt, rcUsedNxt, SolStack))
                    {
                        return(true);               //Check the solution
                    }
                    LKnxt.rcUsed = rcUsedNxt;       //Used cells in the current phase of recursive search
                    if (_Search_ALSChain(LK0, LKnxt, SolStack, szCtrlX, ref limitF))
                    {
                        return(true);      //Recursive Search
                    }
                    SolStack.Pop();        //Pop:Return trial
                }
            }
            return(false);
        }
Beispiel #11
0
        private void ALSXZ_SolResult(int RCC, UALS UA, UALS UB)
        {
            string st = "ALS-XZ " + ((RCC.BitCount() == 1)? "(Singly Linked)": "(Doubly Linked)");

            Result = st;

            if (SolInfoB)
            {
                foreach (var P in UA.UCellLst)
                {
                    P.SetNoBBgColor(P.FreeB, AttCr2, SolBkCr);
                }
                foreach (var P in UB.UCellLst)
                {
                    P.SetNoBBgColor(P.FreeB, AttCr2, SolBkCr2);
                }

                st        += "\r ALS1: " + UA.ToStringRCN();
                st        += "\r ALS2: " + UB.ToStringRCN();
                st        += "\r  RCC: #" + RCC.ToBitStringN(9);
                ResultLong = st;
            }
        }
 public UALSPair(UALS ALSpre, UALS ALSnxt, int RCC, int nRCC, Bit81 rcB = null)
 {
     this.ALSpre = ALSpre; this.ALSnxt = ALSnxt; this.RCC = RCC; this.nRCC = nRCC;
     this.rcUsed = rcB ?? (ALSpre.B81 | ALSnxt.B81);
 }
Beispiel #13
0
 public IEnumerable <UCell> _GetRestCells(UALS ISP, int selB)
 {
     return(pBDL.IEGetCellInHouse(ISP.tfx, selB).Where(P => !ISP.B81.IsHit(P.rc)));
 }
Beispiel #14
0
        public int PrepareALSLinkMan(int nPls)    //QALS_Search
        {
            if (ALSLst != null)
            {
                return(ALSLst.Count());
            }
            int ALSSizeMax = GNPXApp000.ALSSizeMax;

            int mx = 0; //tentative ID, reset later

            ALSLst = new List <UALS>();
            List <int> singlyMan = new List <int>();

            for (int nn = 1; nn <= nPls; nn++)
            {
                for (int tf = 0; tf < 27; tf++)
                {
                    List <UCell> Pcells = pBDL.IEGetCellInHouse(tf, 0x1FF).ToList();
                    if (Pcells.Count < 1)
                    {
                        continue;
                    }
                    int szMax = Min(Pcells.Count, 8 - nn);
                    szMax = Min(szMax, ALSSizeMax);  //ALS size maximum value
                    for (int sz = 1; sz <= szMax; sz++)
                    {
                        Combination cmb = new Combination(Pcells.Count, sz);
                        while (cmb.Successor())
                        {
                            int FreeB = 0;
                            Array.ForEach(cmb.Index, q => FreeB |= Pcells[q].FreeB);
                            if (FreeB.BitCount() != (sz + nn))
                            {
                                continue;
                            }
                            List <UCell> Q = new List <UCell>();
                            Array.ForEach(cmb.Index, q => Q.Add(Pcells[q]));

                            //Check for existence of ALS with the same configuration
                            UALS UA = new UALS(mx++, sz, tf, FreeB, Q);
                            if (!UA.IsPureALS())
                            {
                                continue;
                            }
                            int hs = UA.GetHashCode();
                            if (singlyMan.Any(p => p == hs))
                            {
                                UA.singly = false;
                            }
                            else
                            {
                                singlyMan.Add(hs);
                            }

                            ALSLst.Add(UA);
                        }
                    }
                }
            }

            ALSLst.Sort();
            int ID = 0;

            ALSLst.ForEach(P => P.ID = ID++);
            // ALSLst.ForEach(P=>WriteLine(P));
            return(ALSLst.Count());
        }
Beispiel #15
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);
        }
Beispiel #16
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);
        }
        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);
        }
 public readonly int nRCC = -1; //no:0...8(In the case of doubly, make links individually)
 public LinkCellALS(UCell UC, UALS ALS, int nRCC)
 {
     this.UC = UC; this.ALS = ALS; this.nRCC = nRCC;
 }