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); }
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"; }
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; } }
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; }
//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); } } } }
//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"; }
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()}" ); }
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); }
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); }
public IEnumerable <UCell> _GetRestCells(UALS ISP, int selB) { return(pBDL.IEGetCellInHouse(ISP.tfx, selB).Where(P => !ISP.B81.IsHit(P.rc))); }
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()); }
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 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; }