private int _GroupedNL_CheckSolution(GroupedLink GLK0, GroupedLink GLKnxt, Stack <GroupedLink> SolStack, Bit81 UsedCs) { bool SolFound = false; int SolType = pSprLKsMan.Check_SuperLinkSequence(GLKnxt, GLK0)? 1: 2; //1:Continuous 2:DisContinuous if (SolType == 1) //<>continuous { List <GroupedLink> SolLst = SolStack.ToList(); //___Debug_Print_GNLChain(SolStack); SolLst.Reverse(); SolLst.Add(GLK0); Bit81 UsedCsTmp = new Bit81(UsedCs); SetUsed(ref UsedCsTmp, GLKnxt); foreach (var LK in SolLst.Where(P => (P.type == W))) { int noB = 1 << LK.no; Bit81 SolBP = new Bit81(); LK.UGCellsA.ForEach(P => { if ((P.FreeB & noB) > 0) { SolBP.BPSet(P.rc); } }); LK.UGCellsB.ForEach(P => { if ((P.FreeB & noB) > 0) { SolBP.BPSet(P.rc); } }); if (SolBP.BitCount() <= 1) { continue; } foreach (var P in pBDL.Where(p => (p.FreeB & noB) > 0)) { if (UsedCsTmp.IsHit(P.rc)) { continue; } if (!(SolBP - ConnectedCells[P.rc]).IsZero()) { continue; } if ((P.FreeB & noB) == 0) { continue; } P.CancelB |= noB; //exclusion digit SolFound = true; } } var LKpre = SolLst[0]; foreach (var LK in SolLst.Skip(1)) { if (LKpre.type == S && LK.type == S && LK.UGCellsA.Count == 1) { var P = pBDL[LK.UGCellsA[0].rc]; //(for MultiAns code) int noB2 = P.FreeB - ((1 << LKpre.no2) | (1 << LK.no)); if (noB2 > 0) { P.CancelB |= noB2; SolFound = true; } } LKpre = LK; } if (SolFound) { SolCode = 1; } } else { //<>discontinuous int dcTyp = GLK0.type * 10 + GLKnxt.type; UCell P = pBDL[GLK0.UGCellsA[0].rc]; //(for MultiAns code) switch (dcTyp) { case 11: P.FixedNo = GLK0.no + 1; //Cell number determination P.CancelB = P.FreeB.DifSet(1 << (GLK0.no)); SolCode = 1; SolFound = true; //(1:Fixed) break; case 12: P.CancelB = 1 << GLKnxt.no; SolCode = 2; SolFound = true; break;//(2:Exclude from candidates) case 21: P.CancelB = 1 << GLK0.no; SolCode = 2; SolFound = true; break; case 22: if (GLK0.no == GLKnxt.no) { P.CancelB = 1 << GLK0.no; SolFound = true; SolCode = 2; } break; } } if (SolFound) { return(SolType); } return(-1); }
public UGrCells(int tfx, int no) { this.tfx = tfx; this.no = no; B81 = new Bit81(); }
private void SetUsed(ref Bit81 UsedCs, GroupedLink GLKnxt) { UsedCs |= GLKnxt.UGCellsB.B81; }
public IEnumerable <GroupedLink> IEGet_SuperLink(GroupedLink GLKpre) { int SWCtrl = GLKpre.type; bool ALSpre = GLKpre is ALSLink; if (GLKpre.UGCellsB.Count == 1) { UCell U = GLKpre.UGCellsB[0]; List <UCellLink> Plst = CeLKMan.CeLK81[U.rc]; if (Plst != null) { foreach (var LK in Plst) { if (ALSpre && LK.type != W) { continue; } GroupedLink GLK = new GroupedLink(LK); if (Check_SuperLinkSequence(GLKpre, GLK)) { yield return(GLK); } } } } if (GNPXApp000.GMthdOption["GroupedCells"] == "1") { foreach (var GP in GLKMan.GrpCeLKLst) { if (ALSpre && GP.type != W) { continue; } if (!GLKpre.UGCellsB.EqualsRC(GP.UGCellsA)) { continue; } if (GLKpre.no2 != GP.no) { continue; } if (Check_SuperLinkSequence(GLKpre, GP)) { yield return(GP); } } } if (GNPXApp000.GMthdOption["ALS"] == "1" && ALSMan.AlsInnerLink != null) { if (GLKpre.type == W) { foreach (var GP in ALSMan.AlsInnerLink.Where(p => (p.ALSbase.Level == 1))) { if (GLKpre.no2 != GP.no) { continue; } if (GLKpre.UGCellsB.Equals(GP.UGCellsA)) { yield return(GP); } } } } if (ALSpre) { ALSLink ALK = GLKpre as ALSLink; int noB = 1 << ALK.no2; Bit81 BPnoB = new Bit81(pBDL, noB); Bit81 BP = BPnoB & ALK.UGCellsB.B81; // ALK.UGCellsB.ForEach(P=>{ if((P.FreeB&noB)>0) BP.BPSet(P.rc); }); Bit81 UsedCs = GLKpre.UsedCs; for (int tfx = 0; tfx < 27; tfx++) { Bit81 HS = BPnoB & pHouseCells[tfx]; if (!(BP - HS).IsZero()) { continue; } if ((HS - BP).IsZero()) { continue; } Bit81 NxtBP = HS - BP - UsedCs; if (NxtBP.IsZero()) { continue; } //C WriteLine("\n tfx:"+tfx ); //C WriteLine( " BP:"+BP ); //C WriteLine( " HS:"+HS ); //C WriteLine( "HS-BP:"+(HS-BP) ); //C WriteLine( "NxtBP:"+NxtBP ); List <UCell> NxtCs = NxtBP.ToList().ConvertAll(rc => pBDL[rc]); for (int k = 1; k < (1 << NxtCs.Count); k++) { UGrCells NxtGrpdCs = new UGrCells(tfx, ALK.no2); int kb = k; for (int n = 0; n < NxtCs.Count; n++) { if ((kb & 1) > 0) { NxtGrpdCs.Add(new UGrCells(NxtCs[n], ALK.no2)); } kb >>= 1; } GroupedLink GP = new GroupedLink(GLKpre.UGCellsB, NxtGrpdCs, tfx, W); //C WriteLine( GP ); yield return(GP); } } } yield break; }
public UGrCells(UCell X, int no) { this.tfx = -9; this.no = no; B81 = new Bit81(); this.Add(X); }
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); }
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); }
} //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); }
private bool _ALS_DeathBlossomSubEx(int sz, bool stmLinked = false) { int szM = (stmLinked? sz - 1: sz); foreach (var SC in pBDL.Where(p => p.FreeBC == sz)) //Stem Cell { if (pAnMan.CheckTimeOut()) { return(false); } List <LinkCellALS> LinkCeAlsLst = ALSMan.LinkCeAlsLst[SC.rc]; if (LinkCeAlsLst == null || LinkCeAlsLst.Count < sz) { continue; } int nxt = 0, PFreeB = SC.FreeB; var cmb = new Combination(LinkCeAlsLst.Count, szM); //Select szM ALSs in Combination while (cmb.Successor(nxt)) { int FreeB = SC.FreeB, AFreeB = 0x1FF; for (int k = 0; k < szM; k++) { nxt = k; var LK = LinkCeAlsLst[cmb.Index[k]]; //Link[cell-ALS] if ((FreeB & (1 << LK.nRCC)) == 0) { goto LNxtCmb; } FreeB = FreeB.BitReset(LK.nRCC); //nRCC:RCC of stemCell-ALS AFreeB &= LK.ALS.FreeB; if (AFreeB == 0) { goto LNxtCmb; } } if (stmLinked) { if (FreeB.BitCount() != 1 || (FreeB & AFreeB) == 0) { continue; } int no = FreeB.BitToNum(); int noB = FreeB; Bit81 Ez = new Bit81(); for (int k = 0; k < szM; k++) { var ALS = LinkCeAlsLst[cmb.Index[k]].ALS; var UClst = ALS.UCellLst; foreach (var P in UClst.Where(p => (p.FreeB & noB) > 0)) { Ez.BPSet(P.rc); } } foreach (var P in ConnectedCells[SC.rc].IEGet_rc().Select(rc => pBDL[rc])) { if ((P.FreeB & noB) == 0) { continue; } if ((Ez - ConnectedCells[P.rc]).IsZero()) { P.CancelB = noB; SolCode = 2; } } if (SolCode < 1) { continue; } var LKCAsol = new List <LinkCellALS>(); Array.ForEach(cmb.Index, nx => LKCAsol.Add(LinkCeAlsLst[nx])); _DeathBlossom_SolResult(LKCAsol, SC, no, stmLinked); if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } else if (FreeB == 0 && AFreeB > 0) { AFreeB = AFreeB.DifSet(SC.FreeB); foreach (var no in AFreeB.IEGet_BtoNo()) { int noB = (1 << no); Bit81 Ez = new Bit81(); for (int k = 0; k < sz; k++) { var ALS = LinkCeAlsLst[cmb.Index[k]].ALS; var UClst = ALS.UCellLst; foreach (var P in UClst.Where(p => (p.FreeB & noB) > 0)) { Ez.BPSet(P.rc); } } foreach (var P in pBDL.Where(p => (p.FreeB & noB) > 0)) { if ((Ez - ConnectedCells[P.rc]).IsZero()) { P.CancelB = noB; SolCode = 2; } } if (SolCode < 1) { continue; } var LKCAsol = new List <LinkCellALS>(); Array.ForEach(cmb.Index, nx => LKCAsol.Add(LinkCeAlsLst[nx])); _DeathBlossom_SolResult(LKCAsol, SC, no, stmLinked); if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } } LNxtCmb: continue; } } return(false); }
private int _NL_CheckSolution(UCellLink LK0, UCellLink LKnxt, Stack <UCellLink> SolStack, Bit81 UsedCells) { bool SolFound = false; int SolType = CeLKMan.Check_CellCellSequence(LKnxt, LK0)? 1: 2; //1:Continuous 2:DisContinuous if (SolType == 1) //===== continuous ===== //=== Change WeakLink to StrongLink { List <UCellLink> SolLst = SolStack.ToList(); Bit81 UsedCellsT = UsedCells | (new Bit81(LK0.rc1)); foreach (var L in SolLst) { int noB = 1 << L.no; foreach (var P in pBDL.IEGetCellInHouse(L.tfx, noB)) { if (UsedCellsT.IsHit(P.rc)) { continue; } P.CancelB |= noB; SolFound = true; } } //=== S-S (There are no other numbers) SolLst.Reverse(); SolLst.Add(LK0); var LKpre = SolLst[0]; foreach (var LK in SolLst.Skip(1)) { if (LKpre.type == 1 && LK.type == 1) //S-S { UCell P = pBDL[LK.rc1]; int noB = P.FreeB.DifSet((1 << LKpre.no) | (1 << LK.no)); if (noB > 0) { P.CancelB = noB; SolFound = true; } } LKpre = LK; } if (SolFound) { SolCode = 2; } } else if (SolType == 2) //===== discontinuous ===== { UCell P = pBDL[LK0.UCe1.rc]; //(for MultiAns code) int dcTyp = LK0.type * 10 + LKnxt.type; switch (dcTyp) { case 11: P.FixedNo = LK0.no + 1; //Cell number determination P.CancelB = P.FreeB.DifSet(1 << (LK0.no)); SolCode = 1; SolFound = true; //(1:Fixed) break; case 12: P.CancelB = 1 << LKnxt.no; SolCode = 2; SolFound = true; break;//(2:Exclude from candidates) case 21: P.CancelB = 1 << LK0.no; SolCode = 2; SolFound = true; break; case 22: if (LK0.no == LKnxt.no) { P.CancelB = 1 << LK0.no; SolFound = true; SolCode = 2; } break; } } if (SolFound) { return(SolType); } return(-1); }
private bool _NL_Search(UCellLink LK0, UCellLink LKpre, Stack <UCellLink> SolStack, Bit81 UsedCells, int szCtrl) { if (szCtrl <= 0) { return(false); } foreach (var LKnxt in CeLKMan.IEGet_CeCeSeq(LKpre)) //links that satisfy concatenation conditions { int rc2Nxt = LKnxt.rc2; if (UsedCells.IsHit(rc2Nxt)) { continue; //UsedCells does not include Origin Cell } { //===== Chain Search ===== SolStack.Push(LKnxt); //___Debug_Print_NLChain(SolStack); if (rc2Nxt == LK0.rc1 && szCtrl == 1) { if (SolStack.Count > 2) //Loop was formed (the next cell matches the Origin Cell) { int SolType = _NL_CheckSolution(LK0, LKnxt, SolStack, UsedCells); //Solved? if (SolType > 0) { if (SolInfoB) { _NL_SolResult(LK0, LKnxt, SolStack, SolType); } if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(false)) { return(true); } } } } else { Bit81 UsedCellsNxt = UsedCells | (new Bit81(rc2Nxt)); //Create a new bit expression of used cell _NL_Search(LK0, LKnxt, SolStack, UsedCellsNxt, szCtrl - 1); //Next step Search(recursive call if (SolCode > 0) { return(true); } } SolStack.Pop(); //Failure(Cancel link extension processing) } //----------------------------- } return(false); }
//XYwing is an algorithm that consists of two WeakLinks with common cells. //http://csdenpe.web.fc2.com/page42.html public bool XYwing( ) { Prepare(); CeLKMan.PrepareCellLink(2); //Generate WeakLinks if (BVCellLst == null) { BVCellLst = pBDL.FindAll(p => (p.FreeBC == 2)); //Generate BVs(BV:bivalue). } if (BVCellLst.Count < 3) { return(false); } bool XYwing = false; foreach (var P0 in BVCellLst) //Choose one BV_Cell(=>PS) { List <UCellLink> BVLKLst = CeLKMan.IEGetRcNoBTypB(P0.rc, 0x1FF, 2).Where(R => R.BVFlag).ToList(); //Extract WeakLinks starting from P0 //foreach( var P in BVLKLst ) WriteLine(P); if (BVLKLst.Count < 2) { continue; } var cmb = new Combination(BVLKLst.Count, 2); int nxt = 1; while (cmb.Successor(nxt)) //Combine two WLinks from BVLKLst { UCellLink LKA = BVLKLst[cmb.Index[0]], LKB = BVLKLst[cmb.Index[1]]; //( UCell Q = LKA.UCe2, R = LKB.UCe2; if (Q.rc == R.rc || LKA.no == LKB.no) { continue; //Two WLinks have different end and different digits } Bit81 Q81 = ConnectedCells[LKA.rc2] & ConnectedCells[LKB.rc2]; if (Q81.Count <= 0) { continue; //Two WLinks have cells connected indirectly } int noB = Q.FreeB.DifSet(1 << LKA.no) & R.FreeB.DifSet(1 << LKB.no); if (noB == 0) { continue; //Two WLinks have common digit(=>no). } int no = noB.BitToNum(); string msg2 = ""; foreach (var A in Q81.IEGetUCeNoB(pBDL, noB)) { if (A == P0 || A == Q || A == R) { continue; } A.CancelB = noB; XYwing = true; //cell(A)/digit(no) can be excluded if (SolInfoB) { msg2 += $" {A.rc.ToRCNCLString()}(#{no+1})"; } } if (XYwing) { SolCode = 2; P0.SetNoBColor(P0.FreeB, AttCr); P0.SetCellBgColor(SolBkCr); Q.SetCellBgColor(SolBkCr); R.SetCellBgColor(SolBkCr); string msg0 = $" Pivot: {_XYwingResSub(P0)}"; string msg1 = $" Pin: {_XYwingResSub(R)} ,{_XYwingResSub(Q)}"; Result = "XY Wing" + msg0; if (SolInfoB) { ResultLong = $"XY Wing\r {msg0}\r {msg1}\r Eliminated:{msg2}"; } if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP()) { return(true); } XYwing = false; } } } return(false); }
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); }
public bool CannibalisticFMFish_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 = Bas.BaseB81 - Cov.CoverB81; if (FinB81.Count == 0) { foreach (var P in Cov.CannFin.IEGetUCeNoB(pBDL, noB)) { P.CancelB = noB; SolCode = 2; } if (SolCode > 0) { if (SolInfoB) { _Fish_FishResult(no, sz, Bas, Cov, (FMSize == 27)); //FMSize 27:Franken/Mutant } //WriteLine(ResultLong); //___Debug_CannFish("Cannibalistic"); if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } } else { FinB81 |= Cov.CannFin; Bit81 ELM = null; Bit81 E = (Cov.CoverB81 - Bas.BaseB81) | Cov.CannFin; ELM = new Bit81(); 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)); } //WriteLine(ResultLong); //___Debug_CannFish("Finned Cannibalistic"); if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } } } } } return(false); }
private bool GNL_RecursiveSearch(GroupedLink GLK0, GroupedLink GLKpre, Stack <GroupedLink> SolStack, int szCtrl) { if (szCtrl < 0) { return(false); } Bit81 UsedCs = GLKpre.UsedCs; foreach (var GLKnxt in pSprLKsMan.IEGet_SuperLink(GLKpre)) //links that satisfy concatenation conditions { UGrCells GCsNxt = GLKnxt.UGCellsB; int no = GLKnxt.no; { //===== Chain Search ===== SolStack.Push(GLKnxt); //( link extension --> Push ) ___Debug_Print_GNLChain(SolStack); //Loop was formed (the next cell matches the Origin Cell) if (_GroupedNL_LoopCheck(GLK0, GLKnxt)) { if (szCtrl == 0 && SolStack.Count > 3) { int SolType = _GroupedNL_CheckSolution(GLK0, GLKnxt, SolStack, UsedCs); if (SolType > 0) { if (___GNLCC == 2898) { WriteLine("-----------------"); } ___Debug_Print_GNLChain(SolStack, "<+><+>"); if (SolInfoB) { _GroupedNL_SolResult(GLK0, GLKnxt, SolStack, SolType); } __SolGL = SolCode; if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(false)) { return(false); } Thread.Sleep(10); if ((++SolLimBrk) > (int)SDK_Ctrl.MltAnsOption["OneMethod"]) { SolLimBrk = int.MaxValue; return(false); } } } } else if (!CheckUsed((UsedCs | GLK0.UsedCs), GLKnxt)) { Bit81 UsedCsNxt = new Bit81(UsedCs); //Create a new bit expression of used cell SetUsed(ref UsedCsNxt, GLKnxt); GLKnxt.UsedCs = UsedCsNxt; GNL_RecursiveSearch(GLK0, GLKnxt, SolStack, szCtrl - 1); //Next step Search(recursive call if (SolLimBrk == int.MaxValue) { return(false); } if (SolCode > 0) { return(true); } } SolStack.Pop(); // Failure(Cancel link extension processing --> Pop ) } //----------------------------- } return(false); }
public IEnumerable <UBasCov> IEGet_BaseSet(int sz, int rnk) { if (UGLLst == null) { yield break; } BSstatus = new BaseSet_Status(sz, rnk); List <UGLink> basUGLs = BSstatus.basUGLs; //BaseSet List Bit981 HB981 = BSstatus.HB981; //BaseSet bitPattern Bit324 usedLK = BSstatus.usedLK; //usedLink(by serial number) List <int> usedLKLst = BSstatus.usedLKLst; long RCBN_frameA = 0; _jkc_ = 0; var cmbBas = new Combination(UGLLst.Count, sz); int nxt = int.MaxValue; //(skip function) while (cmbBas.Successor(nxt)) { GeneralLogicGen.ChkBas0++; //***** _jkc_++; // sz=1 *==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* if (sz == 1) { UGLink UGL = UGLLst[cmbBas.Index[0]]; if (UGL.UC is UCell) { goto LNextSet; //only row/column/block link. } HB981.Clear(); HB981.BPSet(UGL.rcBit81.no, UGL.rcBit81, tfbSet: false); //accumulate rcbn info. in HB981. basUGLs.Clear(); basUGLs.Add(UGL); //set UGL in BaseSet GeneralLogicGen.ChkBas1++; //***** goto LBSFound; //possibility of solution } //=================================================================================================================== // sz>=2 *==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* HB981.Clear(); basUGLs.Clear(); usedLKLst.Clear(); BSstatus.Clear(); RCBN_frameA = 0; int[] _RCB_frameB = new int[9]; for (int k = 0; k < sz; k++) //(r:row c:column b:block n:digit => rcbn) { nxt = k; UGLink UGL = UGLLst[cmbBas.Index[k]]; RCBN_frameA |= UGL.RCBN_frameB; //bit expression of rcbn if (!Check_rcbnCondition(sz, rnk, k, RCBN_frameA)) { goto LNextSet; //### extremely efficient } if (UGL.rcBit81 is Bit81) // ........................ rcb link ........................ { int no = UGL.rcBit81.no; if (k > 0 && HB981.IsHit(no, UGL.rcBit81)) { goto LNextSet; //elements already included in HB981 } HB981.BPSet(no, UGL.rcBit81, tfbSet: true); //accumulate rcbn info. in HB981. usedLKLst.Add(UGL.rcBit81.ID); //(ID=tfx<<4 | no) //[rcb_link type]register ID to used list. _RCB_frameB[no] |= (int)UGL.RCBN_frameB & 0x3FFFFFF; } else // ....................... Cell link ........................ { UCell UC = UGL.UC; int rc = UC.rc; //In UGLLst, rcb-Links is first, and cell-Links is second. //Even in combination, this order is maintained. //Therefore, the condition "cell-links have common parts with rcb-Links?" is satisfied. foreach (var no in UC.FreeB.IEGet_BtoNo(9)) { if (k > 0 && HB981.IsHit(no, rc)) { goto LNextSet; //Not BaseSet as it has no intersection. } HB981.BPSet(no, rc, tfbSet: true); //accumulate rcbn info. in HB981. _RCB_frameB[no] |= rc.ToRCBitPat(); } int IDrc = rc << 4 | 0xF; //( 0xF:Cell type identification flag ) usedLKLst.Add(IDrc); //(ID=rc<<4| no) //[cell type]register ID to used list. } basUGLs.Add(UGL); //set UGL in BaseSet // ........................................................... } BSstatus.RCB_frameB = _RCB_frameB; __UsedLinkToFrame(HB981, usedLKLst, BSstatus); //// if(SDK_Ctrl.UGPMan.stageNo==8 && _usedLKLst_ToRCBString("",usedLKLst)==" c1#3 c1#6"){ //// Board_Check("*** Check_6 ?"); //// } if (SDK_Ctrl.UGPMan.stageNo == 20 && _usedLKLst_ToRCBString("", usedLKLst) == " r3#2 r4#2 r3#8") { WriteLine(_usedLKLst_ToRCBString($"usedLKLst:{_jkc_}", usedLKLst, addFreeBB: true)); Board_Check(); } //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* // Board_Check(); //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2 if (!BSstatus.Check_1()) { goto LNextSet; //A and B are not linked by other link(C). } if (!BSstatus.Check_2()) { goto LNextSet; //Each cell(A) is in a position to link with other cells. } if (!BSstatus.Check_3()) { goto LNextSet; //There is a limit to the number of cells that have no links other than BaseSet. } //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* /* * //if(SDK_Ctrl.UGPMan.stageNo==12 && sz>=3){// && rnk==1 ){ * if(SDK_Ctrl.UGPMan.stageNo==9 && sz>=2){// && rnk==1 ){ * WriteLine($"\r sz:{sz} rnk:{rnk} jkc:{_jkc_}"); * Check_rcbnCondition(sz,rnk,sz,RCBN_frameA,printB:true); * basUGLs.ForEach(P=>WriteLine(P.ToString("BaseSet"))); * } */ LBSFound: usedLK.Clear(); basUGLs.ForEach(P => usedLK.BPSet(P.IDnum)); //IDrc: rc<<17 | 1<<16 UBasCov UBC = new UBasCov(basUGLs, HB981, sz, usedLK); yield return(UBC); //--------------------------------------------------------------------------------------- LNextSet: continue; } yield break; void __UsedLinkToFrame(Bit981 HB981, List <int> usedLKLst, BaseSet_Status BSstatus) { int[] _frame_0 = new int[9]; int[] _frame_1 = new int[9]; Bit81 _frame_T = new Bit81(); int frm, _cellC = 0; foreach (var no in HB981.noBit.IEGet_BtoNo()) { _frame_0[no] = frm = HB981._BQ[no].IEGetRC().Aggregate(0, (Q, rc) => Q | rc.ToRCBitPat()); _frame_1[no] = ___frame_ResetUsed(frm, no, usedLKLst); _frame_T |= HB981._BQ[no]; } Bit81 _frame_81 = new Bit81(_frame_T); usedLKLst.ForEach(P => { if ((P & 0xF) == 0xF) { _frame_81.BPReset(P >> 4); _cellC++; } }); BSstatus._frame_0 = _frame_0; BSstatus._frame_1 = _frame_1; BSstatus._frame_T = _frame_T; BSstatus._frame_81 = _frame_81; BSstatus._cellC = _cellC; //(Number of cell links in BaseSet) } }
public Bit81(Bit81 P) : this() { this._BP[0] = P._BP[0]; this._BP[1] = P._BP[1]; this._BP[2] = P._BP[2]; }
//XY-Chain is an algorithm using Locked which occurs in the concatenation of bivalues. //http://csdenpe.web.fc2.com/page49.html public bool XYChain() { Prepare(); CeLKMan.PrepareCellLink(1); //Generate StrongLink List <int> LKRec = new List <int>(); foreach (var CRL in _GetXYChain(LKRec)) { int rcS = CRL[0].ID, no = CRL[1].ID, noB = (1 << no); Bit81 ELM = ConnectedCells[rcS] - (CRL[0] | CRL[1]); if (ELM.IsZero()) { continue; } Bit81 ELM2 = new Bit81(); bool XYChainF = false; foreach (var E in ELM.IEGetUCeNoB(pBDL, noB)) { if (CRL[0].IsHit(ConnectedCells[E.rc])) { E.CancelB = noB; XYChainF = true; ELM2 |= CRL[0] & ConnectedCells[E.rc]; break; } } if (!XYChainF) { continue; } //===== XY-Chain found ===== SolCode = 2; String SolMsg = "XY Chain"; Result = SolMsg; int rcE; foreach (var P in ELM2.IEGetUCeNoB(pBDL, noB)) { P.SetNoBBgColor(noB, AttCr, SolBkCr); } Bit81 ELM2cpy = new Bit81(ELM2); while ((rcE = ELM2.FindFirstrc()) >= 0) { string stR = ""; Bit81 XYchainB = _SelectLink_XYChain(LKRec, rcS, rcE, noB, ref stR) - ELM2cpy; if (SolInfoB) { SolMsg += "\r " + stR; } foreach (var P in XYchainB.IEGetUCeNoB(pBDL, 0x1FF)) { P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr2); } ELM2.BPReset(rcE); } if (SolInfoB) { ResultLong = SolMsg; } pBDL[rcS].SetNoBBgColor(noB, AttCr, SolBkCr); if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } XYChainF = false; } return(false); }
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 bool ForceChain_HouseEx( ) { if (GNPXApp000.GMthdOption["ForceChainCellHouseOn"] != "1") { return(false); } GroupedLink._IDsetB = false; //ID set for debug Prepare(); pSprLKsMan.PrepareSuperLinkMan(AllF: true); string dspOpt = GNPXApp000.GMthdOption["ForceLx"]; Bit81[] sPass = new Bit81[9]; for (int k = 0; k < 9; k++) { sPass[k] = new Bit81(); } bool solvedA = false; for (int hs0 = 0; hs0 < 27; hs0++) { int noBs = pBDL.IEGetCellInHouse(hs0).Aggregate(0, (Q, P) => Q | (P.FreeB)); bool solvedB = false; foreach (var no0 in noBs.IEGet_BtoNo()) { int noB = (1 << no0); Bit81[] sTrue = new Bit81[9]; for (int k = 0; k < 9; k++) { sTrue[k] = new Bit81(all_1: true); } foreach (var P0 in pBDL.IEGetCellInHouse(hs0, noB)) { USuperLink USLK = pSprLKsMan.get_L2SprLK(P0.rc, no0, FullSearchB: false, DevelopB: false); if (USLK == null || !USLK.SolFound) { goto nextSearch; } for (int k = 0; k < 9; k++) { sTrue[k] &= (USLK.Qtrue[k] - USLK.Qfalse[k]); sTrue[k].BPReset(P0.rc); } } for (int nox = 0; nox < 9; nox++) { if (!sTrue[nox].IsZero()) { solvedB = true; break; } } if (solvedB) { solvedA = true; _ForceChainHouseDispEx(sPass, sTrue, hs0, no0); if (!SDK_Ctrl.MltAnsSearch && dspOpt == "ForceL0") { return(true); } } } if (solvedA && dspOpt == "ForceL1") { _ForceChainHouseDispEx(sPass, null, hs0, -1); if (!SDK_Ctrl.MltAnsSearch) { return(true); } } nextSearch: continue; } if (solvedA && !SDK_Ctrl.MltAnsSearch && dspOpt == "ForceL2") { _ForceChainHouseDispEx(sPass, null, -1, -1); } return(SolCode > 0); }