//X-Chain is an algorithm using Locked which occurs when concatenating strong and weak links. //http://csdenpe.web.fc2.com/page48.html public bool XChain() { Prepare(); CeLKMan.PrepareCellLink(1); //Generate StrongLink for (int no = 0; no < 9; no++) { int noB = (1 << no); List <int> LKRec = new List <int>(); foreach (var CRL in _GetXChain(no, LKRec)) { int rcS = CRL[0].ID; //Bit81.ID is used for information exchange(irregular use) Bit81 ELM = (ConnectedCells[rcS] & CRL[1]) - CRL[2]; //CRL[2]:exclude chain of only two links(trivial solution). if (ELM.IsZero()) { continue; //ELM:eliminatable cells } //===== X-Chain found ===== SolCode = 2; foreach (var P in ELM.IEGetUCeNoB(pBDL, noB)) { P.CancelB = noB; } string SolMsg = $"X-Chain #{(no+1)}"; Result = SolMsg; if (SolInfoB) { Bit81 LKRecB = _SelectLink_XChain(LKRec, rcS, ELM, noB); //Extract related-Link CRL[0] &= LKRecB; CRL[1] &= LKRecB; Color Cr = _ColorsLst[0]; Color Cr1 = Color.FromArgb(255, Cr.R, Cr.G, Cr.B); Color Cr2 = Color.FromArgb(120, Cr.R, Cr.G, Cr.B); //(Lightness adjustment) foreach (var P in CRL[0].IEGetUCeNoB(pBDL, noB)) { P.SetNoBBgColor(noB, AttCr, Cr2); } foreach (var P in CRL[1].IEGetUCeNoB(pBDL, noB)) { P.SetNoBBgColor(noB, AttCr, Cr1); } pBDL[rcS].SetNoBBgColor(noB, AttCr, SolBkCr); ResultLong = SolMsg;; } if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } } return(false); }
public int PrepareUGLinkMan(bool printB = false) { UGLLst = new List <UGLink>(); UGLink.IDnum0 = 0; //In UGLLst, rcb-Links is first, and cell-Links is second. This order is used in the algorithm. // 1)rcb-Links for (int no = 0; no < 9; no++) //no:digit { Bit81 BPnoB = new Bit81(pBDL, (1 << no)); for (int tfx = 0; tfx < 27; tfx++) //tfx:house { Bit81 Q = pHouseCells[tfx] & BPnoB; if (Q.IsZero()) { continue; } Q.no = no; Q.ID = (tfx << 4) | no; //ID is the usage within this algorithm(UGLinkMan). if (UGLLst.All(P => (P.rcBit81.no != no || P.rcBit81 != Q))) { UGLLst.Add(new UGLink(Q)); } //Q is unique? // else{ usedLKIgnrLst.Add(Q.ID); } //House is different but cells pattern is the same. } } // 2)cell-Links foreach (var UC in pBDL.Where(p => p.No == 0)) { UGLLst.Add(new UGLink(UC)); // cell elements } if (printB) { UGLLst.ForEach(P => WriteLine(P.ToString("prepare"))); // _usedLKLst_ToRCBString("### usedLKIgnrLst",usedLKIgnrLst); } _BDL_B9 = new Bit981(); foreach (var P in pBDL.Where(p => (p.FreeB) > 0)) { foreach (var no in P.FreeB.IEGet_BtoNo()) { _BDL_B9._BQ[no].BPSet(P.rc); } } for (int n = 0; n < 9; n++) { if (_BDL_B9._BQ[n].Count == 0) { _BDL_B9._BQ[n] = null; } } return(UGLLst.Count); }
public Bit981(Bit81 P) : this() { int no = P.no; this._BQ[no] = P; if (!P.IsZero()) { noBit |= (1 << no); } }
//Link between Cell and ALS public void QSearch_Cell2ALS_Link( ) { if (ALSLst == null) { PrepareALSLinkMan(1); } if (LinkCeAlsLst != null) { return; } LinkCeAlsLst = new List <LinkCellALS> [81]; if (ALSLst == null || ALSLst.Count < 2) { return; } foreach (var PA in ALSLst.Where(P => P.singly)) { foreach (var no in PA.FreeB.IEGet_BtoNo()) { int noB = (1 << no); Bit81 H = new Bit81(true); foreach (var P in PA.UCellLst.Where(q => (q.FreeB & noB) > 0)) { H &= pConnectedCells[P.rc]; } if (H.IsZero()) { continue; } foreach (var P in H.IEGetUCeNoB(pBDL, noB)) { var Q = new LinkCellALS(P, PA, no); if (LinkCeAlsLst[P.rc] == null) { LinkCeAlsLst[P.rc] = new List <LinkCellALS>(); } LinkCeAlsLst[P.rc].Add(Q); } } } for (int rc = 0; rc < 81; rc++) { if (LinkCeAlsLst[rc] != null) { LinkCeAlsLst[rc].Sort(); } } }
//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); } }
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); }
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); }
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 _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 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; }
//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); }
} //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); }