//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 string _XYwingResSub(UCell P) { string st = P.rc.ToRCNCLString() + "(#" + P.FreeB.ToBitStringNZ(9) + ")"; return(st); }
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); }
//Search for groupedLink_sequence starting from rc0#no0 as true. public USuperLink Eval_SuperLinkChainEx(int rc0, int no0, bool DevelopB) { try{ int dbX = 0; _dbCC = 0; USuperLink GNL_Result = new USuperLink(rc0, no0); var Qtrue = GNL_Result.Qtrue; var Qfalse = GNL_Result.Qfalse; var chainDesLKT = GNL_Result.chainDesLKT; var chainDesLKF = GNL_Result.chainDesLKF; var rcQue = new Queue <GroupedLink>(); UCell P0 = pBDL[rc0]; //Origin Cell int no0B = 1 << no0; //Origin Digit Qtrue[no0].BPSet(rc0); //P is Cell. R,RR,RRR is GroupedLink {//====================== Start with WeakLink(origin:rc#no0) ====================== foreach (var R in IEGet_SuperLinkFirst(P0, no0).Where(X => X.type == W)) { if (DevelopB) { Write("*1st:" + R.GrLKToString()); __Debug_ChainPrint(R); } R.UsedCs = R.UGCellsA.B81; //set usedcells(accumulate) R.preGrpedLink = null; //GLKnoR0; //set pre-GLink rcQue.Enqueue(R); //enqueue next-GLink to RadiationSearchQueue foreach (var P in R.UGCellsB.Where(p => (p.FreeB & no0B) > 0)) { int no2 = R.no2; Qfalse[no2].BPSet(P.rc); //set p.rc#no2 to false chainDesLKF[P.rc, no2] = R; //�� //record in retroactive chain if (DevelopB) { WriteLine($" 12 W *Rad->{P} --#{no2} is false."); } } } foreach (var nox in pBDL[rc0].FreeB.IEGet_BtoNo().Where(p => p != no0)) { Qfalse[nox].BPSet(rc0); } } //====================== Radiation Search =============================== while (rcQue.Count > 0) { { //----- Distinct ----- var Q2 = rcQue.ToList().Distinct(); rcQue.Clear(); foreach (var X in Q2) { rcQue.Enqueue(X); } //if(DevelopB){ WriteLine(); foreach(var P in rcQue) WriteLine($"--rcQue---{P.GrLKToString()}"); WriteLine(); } } GroupedLink R = rcQue.Dequeue(); //dequeue next element if (DevelopB) { WriteLine($"\r{dbX++}---Queue:" + R.GrLKToString()); } foreach (var RR in IEGet_SuperLink(R).Where(p => p.AvailableF)) //foreach next GLink { RR.preGrpedLink = R; //set preLink if (!(R.UsedCs & RR.UGCellsB.B81).IsZero()) { continue; //Skip by used Cells } if (DevelopB) { WriteLine($"\r {dbX++}--RR:" + RR.GrLKToString()); } RR.UsedCs = R.UsedCs | RR.UGCellsA.B81; if (DevelopB) { __Debug_ChainPrint(RR); WriteLine($"�� {dbX++}-{++chkX}--RR:" + RR.GrLKToString()); } int no2 = RR.no2; //no2:next digit if (RR.type == S) // F->T *=*=* Check connection conditions. case StrongLink *=*=* { if (RR.UGCellsB.Count == 1) //if the link's next element is a single cell { var P = RR.UGCellsB[0]; //P:next cell if (Qtrue[no2].IsHit(P.rc)) { continue; //Already setted. Eliminate unnecessary trials and speed up. } Qtrue[no2].BPSet(P.rc); //set P.rc#no2 is true chainDesLKT[P.rc, no2] = RR; //record in retroactive chain if (DevelopB) { WriteLine($" 31S ->P:{P} ++#{no2} is true."); } foreach (var nox in P.FreeB.IEGet_BtoNo().Where(q => (q != no2))) { Qfalse[nox].BPSet(P.rc); //set p.rc#nox to false if (DevelopB) { WriteLine($" 32S ->P:{P} --#{nox} is false."); } } } } else if (RR.type == W) // T->F *=*=* Check connection conditions. case WeakLink *=*=* { foreach (var P in RR.UGCellsB) //foreach next GLink { Qfalse[no2].BPSet(P.rc); //set P.rc#no2 is false if (DevelopB) { WriteLine($" 40W ->P:{P} ++#{no2} is false."); } chainDesLKF[P.rc, no2] = RR; //record in retroactive chain } if (RR.UGCellsB.Count == 1) //if the link's next element is a single cell { var P = RR.UGCellsB[0]; if (P.FreeBC == 2) //If the next is a binary cell { int nox = P.FreeB.DifSet(1 << no2).BitToNum(); if (Qtrue[nox].IsHit(P.rc)) { continue; //Already setted. Eliminate unnecessary trials and speed up. } Qtrue[nox].BPSet(P.rc); //set P.rc#no2 is true if (DevelopB) { WriteLine($" 41W ->P:{P} ++#{nox} is true."); } GroupedLink RRR = new GroupedLink(P, no2, nox, S); //GLKbv:GLink in cell(P#no2 StrongLink) RRR.preGrpedLink = RR; //set preLink chainDesLKT[P.rc, nox] = RRR; //record in retroactive chain } } } rcQue.Enqueue(RR); //enqueue next-GLink to RadiationSearchQueue //enqueue next-GLink to RadiationSearchQueue } } GNL_Result.SolFound = true; //Solution found return(GNL_Result); } catch (Exception ex) { WriteLine($"{ex.Message}+\r{ex.StackTrace}"); } return(null); }
private bool _ForceChainHouseDispEx(Bit81[] sPass, Bit81[] sTrue, int hs0, int no0) { string dspOpt = GNPXApp000.GMthdOption["ForceLx"]; if (hs0 < 0)// dspOpt:ForceL2" { Result = ResultLong = "ForceChain_House"; if (__SimpleAnalizerB__) { return(true); } pAnMan.SnapSaveGP(true); return(SolCode > 0); } string st0 = "", st2 = ""; for (int nox = 0; nox < 9; nox++) { if (sTrue != null) { if (sTrue[nox].IsZero()) { continue; } foreach (var rc in sTrue[nox].IEGet_rc()) { if (sPass[nox].IsHit(rc)) { continue; } sPass[nox].BPSet(rc); UCell Q = pBDL[rc]; Q.FixedNo = nox + 1; int elm = Q.FreeB.DifSet(1 << nox); Q.CancelB = elm; SolCode = 1; if (SolInfoB) { Q.SetNoBBgColor(1 << nox, Colors.Red, Colors.LightGreen); Q.SetNoBColorRev(elm, Colors.Red); st0 = $"ForceChain_House({_HouseToString(hs0)}/#{(no0+1)}) r{(Q.r+1)}c{(Q.c+1)}/#{(nox+1)} is true"; string st1 = ""; foreach (var P in pBDL.IEGetCellInHouse(hs0, 1 << no0)) { USuperLink USLK = pSprLKsMan.get_L2SprLK(P.rc, no0, FullSearchB: true, DevelopB: false); //Accurate path st1 += "\r" + pSprLKsMan._GenMessage2true(USLK, Q, nox); if (dspOpt != "ForceL2") { P.SetNoBBgColor(1 << no0, Colors.Green, Colors.Yellow); } } st2 = st0 + st1; extRes += "\r" + st2; //(Description of each solution) extRes = extRes.TrimStart(); if (dspOpt == "ForceL0") { Result = ResultLong = st0; if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(false)) { return(true); } extRes = ""; st2 = ""; if (!SDK_Ctrl.MltAnsSearch) { return(true); } } } } } if (SolInfoB && dspOpt == "ForceL1" && st2 != "") { st0 = $"ForceChain_House({_HouseToString(hs0)}/#{(no0+1)})"; Result = ResultLong = st0; if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(false)) { return(true); } extRes = ""; st2 = ""; if (!SDK_Ctrl.MltAnsSearch) { return(true); } } } return(SolCode > 0); }
//EmptyRectangle is an algorithm using cell-to-cell link and ConnectedCells. //http://csdenpe.web.fc2.com/page41.html public bool EmptyRectangle( ) { Prepare(); CeLKMan.PrepareCellLink(1); //Generate StrongLink for (int no = 0; no < 9; no++) //Focused digit { int noB = 1 << no; for (int bx = 0; bx < 9; bx++) //Focused Block { int erB = pBDL.IEGetCellInHouse(bx + 18, noB).Aggregate(0, (Q, P) => Q | (1 << P.nx)); if (erB == 0) { continue; } for (int er = 0; er < 9; er++) //Focused Cell in the Focused Block { int Lr = er / 3, Lc = er % 3; //Block local Row and Column int rxF = 7 << (Lr * 3); //7=1+2+4 (Block local Row r1c123) int cxF = 73 << Lc; //73=1+8+64 (Block local Column r123c1) if ((erB & rxF) == 0 || erB.DifSet(rxF) == 0) { continue; //Row Lr(Row Cndition Check) } if ((erB & cxF) == 0 || erB.DifSet(cxF) == 0) { continue; //Column Lc(Column Cndition Check) } if (erB.DifSet(rxF | cxF) > 0) { continue; //Row Lr and Column Lc(ER Condition Check) } int r1 = bx / 3 * 3 + Lr; //Convert to Absolute Row int c1 = (bx % 3) * 3 + Lc; //Convert to Absolute Column foreach (var P in HouseCells[9 + c1].IEGetUCeNoB(pBDL, noB).Where(Q => Q.b != bx)) { //P:cell in house(column c1), P is outside bx foreach (var LK in CeLKMan.IEGetRcNoBTypB(P.rc, noB, 1))//rc:link end, noB:digit, 1:StrongLink { UCell Elm = pBDL[r1 * 9 + LK.UCe2.c]; if (Elm.b != bx && (Elm.FreeB & noB) > 0) //There is a Digit that can be excluded { EmptyRectangle_SolResult(no, bx, LK, Elm); //solution found if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } } } foreach (var P in HouseCells[0 + r1].IEGetUCeNoB(pBDL, noB).Where(Q => Q.b != bx)) { //P:cell in house(row r1), P is outside bx foreach (var LK in CeLKMan.IEGetRcNoBTypB(P.rc, noB, 1))//rc:link end, noB:digit, 1:StrongLink { UCell Elm = pBDL[LK.UCe2.r * 9 + c1]; if (Elm.b != bx && (Elm.FreeB & noB) > 0) //There is a Digit that can be excluded { EmptyRectangle_SolResult(no, bx, LK, Elm); //solution found if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } } } } } } return(false); }
private string GenMessage2FakeProposition(int rc0, Bit81[] fakeP, USuperLink USLK, UCell Q) //q { string st = ""; foreach (var no in pBDL[rc0].FreeB.IEGet_BtoNo()) { if (fakeP[no].IsHit(rc0)) { st += $"ForceChain_Cell r{(rc0/9+1)}c{(rc0%9)+1}/{(no+1)} is false(contradition)"; st += "\r" + pSprLKsMan._GenMessage2true(USLK, Q, no); st += "\r" + pSprLKsMan._GenMessage2false(USLK, Q, no); } } return(st); }
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 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; }
public RenderTargetBitmap CreateCellImage(UCell P, bool candDisp) { Color crFore = pColorDic["CellForeNo"]; Color crFix = pColorDic["CellFixed"]; Color crBgFix = pColorDic["CellBkgdFix"]; Brush br; var bmp = new RenderTargetBitmap(35, 35, 96, 96, PixelFormats.Default); if (P.ECrLst == null) { P.ECrLst = new List <EColor>(); } EColor EC; var drawVisual = new DrawingVisual(); using (var DC = drawVisual.RenderOpen()){ Color bgcr = Colors.Black; if (P.ECrLst != null && (EC = P.ECrLst.FindLast(p => (p.CellBgCr != Colors.Black))) != null) { bgcr = EC.CellBgCr; } if (P.FixedNo > 0) { if (P.ECrLst == null) { P.ECrLst = new List <EColor>(); } P.ECrLst.Add(new EColor((1 << (P.FixedNo - 1)), crFix)); bgcr = crBgFix; } else if (P.CancelB > 0) { if (P.ECrLst == null) { P.ECrLst = new List <EColor>(); } P.ECrLst.Add(new EColor(P.CancelB, Colors.White, crFix)); //reverse } if (bgcr != Colors.Black) { br = new SolidColorBrush(bgcr); DC.DrawRectangle(br, null, new Rect(0, 0, bmp.Width, bmp.Height)); } int dspB = 0; foreach (int no in P.FreeB.IEGet_BtoNo()) { int noB = (1 << no), noP = no + 1, x = (no % 3) * 12, y = (no / 3) * 12; Point pt = new Point(x + 3, y); List <EColor> ECrLst = P.ECrLst; if (ECrLst == null) { continue; } if (ECrLst.Any(p => p == null)) { WriteLine(P.ToString()); } EC = ECrLst.FindLast(p => (p.noB & noB) > 0); if (EC != null) { Color crF = crFore; if (EC.Nbgcr != Colors.Black) { Brush brBg = new SolidColorBrush(EC.Nbgcr); Rect re = new Rect(x + 1, y, 12, 12); // DC.DrawRectangle(brBg, null, re); crF = Colors.White; } else { crF = EC.Ncr; } br = new SolidColorBrush(crF); DC.DrawText(GF8.GFText(noP.ToString(), br), pt); dspB |= (1 << no); } } if ((dspB = (P.FreeB).DifSet(dspB)) > 0) { br = new SolidColorBrush(crFore); foreach (int no in dspB.IEGet_BtoNo()) { int noB = (1 << no), x = (no % 3) * 12, y = (no / 3) * 12; Point pt = new Point(x + 3, y); int noP = no + 1; DC.DrawText(GF8.GFText(noP.ToString(), br), pt); } } } bmp.Render(drawVisual); return(bmp); }
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); }
public void SDK_TransProbG(string ctrl, bool DspSolB) { if (pGP.AnsNum == null) { Initialize(); } int ixM = 0, ixR = TrPara[8], ixC = 1 - ixR, nx, m, n; switch (ctrl) { case "NumChange": break; case "Checked": break; case "random": break; case "btnPatCVRg": ixM = TrPara[0] = (++TrPara[0]) % 6; for (int k = 0; k < 3; k++) { RCX[ixR, k + 9] = prmX[ixM, k] * 3; } break; case "btnPatCVR123g": nx = RCX[ixR, 9]; ixM = TrPara[1] = (++TrPara[1]) % 6; for (int k = 0; k < 3; k++) { RCX[ixR, k + nx] = prmX[ixM, k] + nx; } break; case "btnPatCVR456g": nx = RCX[ixR, 10]; ixM = TrPara[2] = (++TrPara[2]) % 6; for (int k = 0; k < 3; k++) { RCX[ixR, k + nx] = prmX[ixM, k] + nx; } break; case "btnPatCVR789g": nx = RCX[ixR, 11]; ixM = TrPara[3] = (++TrPara[3]) % 6; for (int k = 0; k < 3; k++) { RCX[ixR, k + nx] = prmX[ixM, k] + nx; } break; case "btnPatCVCg": ixM = TrPara[4] = (++TrPara[4]) % 6; for (int k = 0; k < 3; k++) { RCX[ixC, k + 9] = prmX[ixM, k] * 3; } break; case "btnPatCVC123g": nx = RCX[ixC, 9]; ixM = TrPara[5] = (++TrPara[5]) % 6; for (int k = 0; k < 3; k++) { RCX[ixC, k + nx] = prmX[ixM, k] + nx; } break; case "btnPatCVC456g": nx = RCX[ixC, 10]; ixM = TrPara[6] = (++TrPara[6]) % 6; for (int k = 0; k < 3; k++) { RCX[ixC, k + nx] = prmX[ixM, k] + nx; } break; case "btnPatCVC789g": nx = RCX[ixC, 11]; ixM = TrPara[7] = (++TrPara[7]) % 6; for (int k = 0; k < 3; k++) { RCX[ixC, k + nx] = prmX[ixM, k] + nx; } break; #if false case "btnTransRtg": //clockwise ixR = TrPara[8] = (++TrPara[8]) % 2; ixC = 1 - ixR; subTransLR(ixC); if (ixR == 0) { subTransLR(ixC); } break; #endif case "btnPatCVRCg": case "btnPatCVRCg2": ixR = TrPara[8] = (++TrPara[8]) % 2; ixC = 1 - ixR; if (ctrl == "btnTransRtg") { goto case "btnTransLRg"; //if clockwise,goto horizontal flip } break; case "btnTransLRg": //horizontal flip subTransLR(ixC); break; case "btnTransUDg": //vertical flip subTransUD(ixR); break; //Symmetric transformation case "btnPatCVR123987g": //row 123 nx = RCX[ixR, 9]; m = TrPara[1]; ixM = TrPara[1] = (m + 1) % 6; for (int k = 0; k < 3; k++) { RCX[ixR, k + nx] = prmX[ixM, k] + nx; } nx = RCX[ixR, 11]; n = TrPara[3]; ixM = TrPara[3] = trsX[m, n]; for (int k = 0; k < 3; k++) { RCX[ixR, k + nx] = prmX[ixM, k] + nx; } break; case "btnPatCVC123987g": //Column 123 nx = RCX[ixC, 9]; m = TrPara[5]; ixM = TrPara[5] = (m + 1) % 6; for (int k = 0; k < 3; k++) { RCX[ixC, k + nx] = prmX[ixM, k] + nx; } nx = RCX[ixC, 11]; n = TrPara[7]; ixM = TrPara[7] = trsX[m, n]; for (int k = 0; k < 3; k++) { RCX[ixC, k + nx] = prmX[ixM, k] + nx; } break; case "btnPatCVR46g": //row 46 nx = RCX[ixR, 10]; ixM = TrPara[2] = (TrPara[2] + 3) % 6; for (int k = 0; k < 3; k++) { RCX[ixR, k + nx] = prmX[ixM, k] + nx; } break; case "btnPatCVC46g": //Column 46 nx = RCX[ixC, 10]; ixM = TrPara[6] = (TrPara[6] + 3) % 6; for (int k = 0; k < 3; k++) { RCX[ixC, k + nx] = prmX[ixM, k] + nx; } break; } for (int j = 0; j < 2; j++) { for (int k = 0; k < 9; k++) { nx = RCX[j, k / 3 + 9]; RCX[j + 2, k] = RCX[j, nx + k % 3]; } } List <UCell> UCL = new List <UCell>(); int[] AnsN2 = new int[81]; int r, c, w; for (int rc = 0; rc < 81; rc++) { r = RCX[ixR + 2, rc / 9]; c = RCX[ixC + 2, rc % 9]; if (ixR == 1) { w = r; r = c; c = w; } int rc2 = r * 9 + c; UCell P = UPbas.BDL[rc2]; UCL.Add(new UCell(rc, P.No, P.FreeB)); AnsN2[rc] = UPbas.AnsNum[rc2]; } UPuzzle UP = pGP.Copy(0, 0); UP.BDL = UCL; UP.AnsNum = AnsN2; if (ID >= 0) { pGNP.SDKProbLst[ID] = UP; } else { UP.ID = pGP.ID = 0; pGNP.SDKProbLst.Add(UP); } if (!DspSolB) { UP.BDL.ForEach(P => { P.No = Max(P.No, 0); }); } pGNP.CurrentPrbNo = ID; SetIDCode(TrPara, AnsN2); /* * string st="RCX:"; * for(int j=0; j<4; j++ ){ * for(int k=0; k<12; k++ ) st+=" "+RCX[j,k]; * st+=" / "; * } * for(int k=0; k<9; k++ ) st+=" "+TrPara[k]; * st+="//"; * int[] BPw=new int[3]; * for(int k=9; k<12; k++ ){BPw[k-9]=TrPara[k]; st+=" "+TrPara[k]; } * WriteLine(st); * * Bit81 BP=new Bit81(BPw); * WriteLine(BP); */ }
public string SDK_Nomalize(bool DspSolB, bool NrmlNum) { int[] TPw = new int[18]; List <int[]> TPLst = new List <int[]>(); if (pGP.AnsNum == null) { Initialize(); //Solve } #region Standardization(Pattern) RCX = new int[4, 12]; for (int k = 0; k < 9; k++) { RCX[0, k] = RCX[1, k] = k; } for (int k = 0; k < 3; k++) { RCX[0, k + 9] = RCX[1, k + 9] = k * 3; } int minV = int.MaxValue; //===== step1 ===== for (int tx = 0; tx < 2; tx++) { TPw[8] = tx; for (int rx0 = 0; rx0 < 6; rx0++) { TPw[0] = rx0; SetRCX(0, TPw); for (int rx1 = 0; rx1 < 6; rx1++) { TPw[1] = rx1; SetRCX(1, TPw); for (int cx4 = 0; cx4 < 6; cx4++) { TPw[4] = cx4; SetRCX(4, TPw); for (int cx5 = 0; cx5 < 6; cx5++) { TPw[5] = cx5; SetRCX(5, TPw); SDK_TransIX(TPw); if (TPw[9] > minV) { continue; } minV = TPw[9]; int[] TPtmp = new int[18]; TPw.CopyTo(TPtmp, 0); TPLst.Add(TPtmp); } } } } } TPLst.Sort((A, B) => (A[9] - B[9])); //===== step2 ===== minV = TPLst[0][9]; TPLst = TPLst.FindAll(P => P[9] == minV).ToList(); int TPLstCount = TPLst.Count; for (int hx = 0; hx < TPLstCount; hx++) { TPw[8] = TPLst[hx][8]; SetRCX(8, TPw); for (int mx = 0; mx < 18; mx++) { TPw[mx] = TPLst[hx][mx]; if (mx < 9) { SetRCX(mx, TPw); } } for (int cx6 = 0; cx6 < 6; cx6++) { TPw[6] = cx6; SetRCX(6, TPw); for (int cx7 = 0; cx7 < 6; cx7++) { TPw[7] = cx7; SetRCX(7, TPw); SDK_TransIX(TPw); if (TPw[9] > minV) { continue; } minV = TPw[9]; int[] TPtmp = new int[18]; TPw.CopyTo(TPtmp, 0); TPLst.Add(TPtmp); } } } TPLst.Sort((A, B) => (A[9] - B[9])); //===== step3 ===== minV = TPLst[0][9]; TPLst = TPLst.FindAll(P => P[9] == minV).ToList(); minV = TPLst[0][10]; TPLstCount = TPLst.Count; for (int hx = 0; hx < TPLstCount; hx++) { TPw[8] = TPLst[hx][8]; SetRCX(8, TPw); for (int mx = 0; mx < 18; mx++) { TPw[mx] = TPLst[hx][mx]; if (mx < 9) { SetRCX(mx, TPw); } } for (int rx2 = 0; rx2 < 6; rx2++) { TPw[2] = rx2; SetRCX(2, TPw); for (int rx3 = 0; rx3 < 6; rx3++) { TPw[3] = rx3; SetRCX(3, TPw); SDK_TransIX(TPw); if (TPw[10] > minV) { continue; } minV = TPw[10]; int[] TPtmp = new int[18]; TPw.CopyTo(TPtmp, 0); TPLst.Add(TPtmp); } } } TPLst.Sort((A, B) => { if (A[10] != B[10]) { return(A[10] - B[10]); } return(A[11] - B[11]); }); minV = TPLst[0][10]; int minV1 = TPLst[0][11]; TPLst = TPLst.FindAll(P => (P[10] == minV && P[11] == minV1)).ToList(); string[] stLst = new string[TPLst.Count]; for (int k = 0; k < TPLst.Count; k++) { TPLst[k].CopyTo(TrPara, 0); SetRCX(8, TPw); for (int mx = 0; mx < 9; mx++) { SetRCX(mx, TrPara); } SDK_TransIX(TrPara, TransB: true, DspSolB: DspSolB); string st = pGNP.SDKCntrl.Get_SDKNumPattern(TrPara, pGP.AnsNum);//Latin square st += TransToString(TrPara); stLst[k] = st; TrPara[17] = k; for (int n = 0; n < TrPara.Count(); n++) { TPLst[k][n] = TrPara[n]; } /* * string st="RCX:"; * for(int j=0; j<4; j++ ){ * for(int m=0;m<12; m++ ) st+=" "+RCX[j,m]; * st+=" / "; * } * * for(int m=0; m<9; m++ ) st+=" "+TrPara[m]; * st+="//"; * int[] IDC=new int[4]; * for(int m=9; m<13; m++ ){ IDC[m-9]=TrPara[m]; st+=" "+TrPara[k]; } * WriteLine(st); * // Bit81 BP=new Bit81(IDC); * // WriteLine(BP); */ } TPLst.Sort((A, B) => { for (int k = 9; k < A.Count(); k++) { if (A[k] != B[k]) { return(A[k] - B[k]); } } return(0); }); TrPara = TPLst[0]; SetRCX(8, TrPara); for (int mx = 0; mx < 8; mx++) { SetRCX(mx, TrPara); } #endregion //Standardization(Latin square) SDK_TransIX(TrPara, TransB: true, DspSolB: DspSolB); if (NrmlNum) { int[] chgNum = new int[10]; int NN = TrPara[15]; for (int k = 0; k <= 9; k++) { chgNum[9 - k] = NN % 10; NN /= 10; } for (int rc = 0; rc < 81; rc++) { int No = pGP.AnsNum[rc]; UCell P = pGP.BDL[rc]; if (P.No > 0) { pGP.AnsNum[rc] = P.No = chgNum[No]; } else { pGP.AnsNum[rc] = P.No = -chgNum[-No]; } } } /* * string po="◆"; * for(int k=0; k<18; k++ ) po+=" "+TrPara[k]; * WriteLine(po); */ return(stLst[TrPara[17]]); }
public UCellLink(UCell UCe1, UCell UCe2, int no, int type) { this.UCe1 = UCe1; this.UCe2 = UCe2; this.no = no; this.type = type; }
private bool _ForceChainCellDispEx(Bit81[] sPass, Bit81[] sTrue, int rc0) //q { string dspOpt = GNPXApp000.GMthdOption["ForceLx"]; if (rc0 < 0) //dspOpt:"ForceL2" { Result = ResultLong = "ForceChain_Cell"; if (__SimpleAnalizerB__) { return(true); } pAnMan.SnapSaveGP(true); return(SolCode > 0); } UCell P0 = pBDL[rc0]; string st0 = "", st2 = ""; for (int nox = 0; nox < 9; nox++) { if (sTrue[nox].IsZero()) { continue; } foreach (var rc in sTrue[nox].IEGet_rc()) { if (sPass[nox].IsHit(rc)) { continue; } sPass[nox].BPSet(rc); UCell Q = pBDL[rc]; Q.FixedNo = nox + 1; int elm = Q.FreeB.DifSet(1 << nox); Q.CancelB = elm; SolCode = 1; if (SolInfoB) //SolInfoB:Flag whether to generate solution information { if (dspOpt != "ForceL2") { P0.SetNoBBgColor(P0.FreeB, Colors.Green, Colors.Yellow); } Q.SetNoBBgColor(1 << nox, Colors.Red, Colors.LightGreen); Q.SetNoBColorRev(elm, Colors.Red); st0 = $"ForceChain_Cell r{(Q.r+1)}c{(Q.c+1)}/{(nox+1)} is true"; //st0:Title of each solution string st1 = ""; foreach (var no in pBDL[rc0].FreeB.IEGet_BtoNo()) { USuperLink USLK = pSprLKsMan.get_L2SprLKEx(rc0, no, FullSearchB: false, DevelopB: false); st1 += "\r" + pSprLKsMan._GenMessage2true(USLK, Q, nox); //st1:Exact GroupedLink path } st2 = st0 + st1; //st2:Description of each solution Result = ResultLong = st0; extRes += "\r" + st2; //(Description of each solution) extRes = extRes.TrimStart(); if (dspOpt == "ForceL0") { if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(false)) { return(true); } extRes = ""; st2 = ""; } } } if (SolInfoB && dspOpt == "ForceL1" && st2 != "") { Result = ResultLong = $"ForceChain_Cell (#{nox+1})"; if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(false)) { return(true); } st2 = ""; extRes = ""; } } return(SolCode > 0); }
//##### There is a bug ##### public USuperLink Eval_SuperLinkChain(int rc0, int no0, bool Gbreak, int typeSel, bool DevelopB) { try{ int dbX = 0; USuperLink USLK = new USuperLink(rc0, no0); var Qtrue = USLK.Qtrue; var Qfalse = USLK.Qfalse; var chainDesLKT = USLK.chainDesLKT; var chainDesLKF = USLK.chainDesLKF; var rcQue = new Queue <GroupedLink>(); UCell P0 = pBDL[rc0]; //Origin Cell int no0B = 1 << no0; //Origin Digit Qtrue[no0].BPSet(rc0); GroupedLink GLKnoR0 = new GroupedLink(P0, no0, no0, W, rootF: true); GLKnoR0.preGrpedLink = null; chainDesLKT[rc0, no0] = GLKnoR0; if ((typeSel & 2) > 0)//====================== Start with WeakLink(origin:rc#no0) ====================== { foreach (var GLKH in IEGet_SuperLinkFirst(P0, no0).Where(X => X.type == W)) { if (DevelopB) { WriteLine("*1st:" + GLKH.GrLKToString()); } GLKH.UsedCs |= GLKH.UGCellsB.B81; //set usedcells(accumulate) GLKH.preGrpedLink = GLKnoR0; //set pre-GLink rcQue.Enqueue(GLKH); //enqueue next-GLink to RadiationSearchQueue foreach (var P in GLKH.UGCellsB.Where(p => (p.FreeB & no0B) > 0)) { int no2 = GLKH.no2; Qfalse[no2].BPSet(P.rc); //set p.rc#no2 to false chainDesLKF[P.rc, no2] = GLKH; //record in retroactive chain if (Gbreak && Qtrue[no2].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], no2)) { goto FTBreak; //found error } if (P.FreeBC == 2) //If the next is a binary cell { int nox = P.FreeB.DifSet(1 << no2).BitToNum(); //nox:another digit in the cell Qtrue[nox].BPSet(P.rc); //P.rc#nox is true GroupedLink GLKbv = new GroupedLink(P, no2, nox, S); //GLKbv:GLink in cell GLKbv.preGrpedLink = GLKH; //set preLink chainDesLKT[P.rc, nox] = GLKbv; //record in retroactive chain if (DevelopB) { WriteLine($" 12 W *Rad->{P} --#{no2} is false."); } if (Gbreak && Qfalse[nox].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], nox)) { goto FTBreak; //found error } } } } //S start cell, non-conscious digits foreach (var nox in P0.FreeB.IEGet_BtoNo().Where(n => (n != no0))) //non-conscious digits in originCell { Qfalse[nox].BPSet(rc0); // is false } } if ((typeSel & 1) > 0)//====================== Start with StrongLink(origin:rc#no0) ====================== { foreach (var GLKH in IEGet_SuperLinkFirst(P0, no0).Where(X => X.type == S)) { int nox = GLKH.no2; GroupedLink GLKnoR1 = new GroupedLink(P0, no0, nox, W, rootF: false); //nextGLink GLKnoR1.preGrpedLink = GLKnoR0; //set pre-GLink to next-GLink chainDesLKF[rc0, nox] = GLKnoR1; //record in retroactive chain GLKH.UsedCs |= GLKH.UGCellsB.B81; //set usedcells(accumulate) GLKH.preGrpedLink = GLKnoR1; //set pre-GLink rcQue.Enqueue(GLKH); //enqueue next-GLink to RadialSearchQueue if (GLKH.UGCellsB.Count == 1) //if the link's next element is a single cell { int no2 = GLKH.no2; //no2:next digit var P = GLKH.UGCellsB[0]; //P:next cell Qtrue[no2].BPSet(P.rc); //set P.rc#no2 is true chainDesLKT[P.rc, no2] = GLKH; //record in retroactive chain if (Gbreak && Qfalse[no2].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], no2)) { goto FTBreak; //found error } Qtrue[nox].BPSet(P.rc); //set P.rc#no is true GroupedLink GLKno = new GroupedLink(P, nox, no2, W); //GLKno:GLink in cell GLKno.preGrpedLink = GLKH; //set preLink chainDesLKF[P.rc, no2] = GLKno; //record in retroactive chain if (Gbreak && Qtrue[nox].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], nox)) { goto FTBreak; //found error } } } } //====================== Radiation Search =============================== while (rcQue.Count > 0) { GroupedLink R = rcQue.Dequeue(); //dequeue next element if (DevelopB) { WriteLine($"{dbX++}---Queue:" + R.GrLKToString()); } foreach (var GLKH in IEGet_SuperLink(R)) //foreach next GLink { if (DevelopB) { WriteLine($" {dbX++}--GLKH:" + GLKH.GrLKToString()); } if (R.type != GLKH.type && R.UGCellsA.Equals(GLKH.UGCellsB)) { continue; //Skip back links } GLKH.preGrpedLink = R; //set preLink int no2 = GLKH.no2; //no2:next digit if (GLKH.type == S) //Check connection conditions. case StrongLink { if (!(GLKH.UGCellsB.B81 & Qtrue[GLKH.no2]).IsZero()) { continue; //if the next element is setted true, go to the next process } if (GLKH.UGCellsB.Count == 1) //if the link's next element is a single cell { var P = GLKH.UGCellsB[0]; //P:next cell Qtrue[no2].BPSet(P.rc); //set P.rc#no2 is true chainDesLKT[P.rc, no2] = GLKH; //record in retroactive chain if (Gbreak && Qfalse[no2].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], no2)) { goto FTBreak; //found error } foreach (var nox in P.FreeB.IEGet_BtoNo().Where(q => (q != no2))) { Qfalse[nox].BPSet(P.rc); //set p.rc#no2 to false GroupedLink GLKno = new GroupedLink(P, no2, nox, W); //GLKbv:GLink in cell(P#no2 WeakLink) GLKno.preGrpedLink = GLKH; //set preLink chainDesLKF[P.rc, nox] = GLKno; //record in retroactive chain if (Gbreak && Qtrue[nox].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], nox)) { goto FTBreak; //found error } if (DevelopB) { WriteLine($" 31S ->P:{P} --#{nox} is false."); } } } } if (GLKH.type == W) //Check connection conditions. case WeakLink { if (!(GLKH.UGCellsB.B81 & Qfalse[GLKH.no2]).IsZero()) { continue; //if the next element is setted false, go to the next process } foreach (var P in GLKH.UGCellsB) //foreach next GLink { Qfalse[no2].BPSet(P.rc); //set P.rc#no2 is true chainDesLKF[P.rc, no2] = GLKH; //record in retroactive chain if (Gbreak && Qtrue[no2].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], no2)) { goto FTBreak; //found error } if (DevelopB) { WriteLine($" 40S ->P:{P} ++#{no2} is false."); } } if (GLKH.UGCellsB.Count == 1) //if the link's next element is a single cell { var P = GLKH.UGCellsB[0]; if (P.FreeBC == 2) //If the next is a binary cell { int nox = P.FreeB.DifSet(1 << no2).BitToNum(); Qtrue[nox].BPSet(P.rc); //set P.rc#no2 is true if (DevelopB) { WriteLine($" 41S ->P:{P} ++#{nox} is true."); } GroupedLink GLKno = new GroupedLink(P, no2, nox, S); //GLKbv:GLink in cell(P#no2 StrongLink) GLKno.preGrpedLink = GLKH; //set preLink chainDesLKT[P.rc, nox] = GLKno; //record in retroactive chain if (Gbreak && Qfalse[nox].IsHit(P.rc) && GenMessage2(USLK, pBDL[P.rc], nox)) { goto FTBreak; //found error } } } } rcQue.Enqueue(GLKH); //enqueue next-GLink to RadiationSearchQueue } } USLK.SolFound = true; //Solution found return(USLK); FTBreak: //Failed USLK.SolFound = false; return(USLK); } catch (Exception ex) { WriteLine($"{ex.Message}+\r{ex.StackTrace}"); } return(null); }
public USuperLink GNL_EvalSuperLinkChain(GroupedLink GLK_000, int rc0, bool DevelopB = false) { try{ if (DevelopB) { WriteLine("\r\r10 *1st:" + GLK_000.GrLKToString()); __Debug_ChainPrint(GLK_000); } int dbX = 0; _dbCC = 0; int no0 = GLK_000.no; USuperLink GNL_Result = new USuperLink(rc0, no0); var Qtrue = GNL_Result.Qtrue; var Qfalse = GNL_Result.Qfalse; Qtrue = GNL_Result.Qtrue; Qfalse = GNL_Result.Qfalse; var rcQue = new Queue <GroupedLink>(); GLK_000.preGrpedLink = null; //sentinel(right GroupedLink's preGrpedLink is null) GLK_000.UsedCs = GLK_000.UGCellsB.B81; //Set Used int contDiscontF = 0; rcQue.Enqueue(GLK_000); //Enqueue first GLK { //====================== First GLK Process ============================================================== GroupedLink RR = GLK_000; int no2 = RR.no2, no2B = 1 << no2; if (RR.type == S) //---------- Check connection conditions. case StrongLink(F->T) ---------- { if (RR.UGCellsB.Count == 1) //if the link's next element is a single cell { UCell RRnxtC = RR.UGCellsB[0]; //RRnxtC:next cell Qtrue[no2].BPSet(RRnxtC.rc); //set RRnxtC.rc#no2 is true foreach (int nox in RRnxtC.FreeB.IEGet_BtoNo().Where(q => (q != no2))) { Qfalse[nox].BPSet(RRnxtC.rc); //set RRnxtC.rc#no2 to false GroupedLink RRR = new GroupedLink(RRnxtC, no2, nox, W); //GLK_ViVal:GLink in cell(RRnxtC#no2 WeakLink) RRR.preGrpedLink = RR; //set preLink rcQue.Enqueue(RRR); //enqueue next-GLink to RadiationSearchQueue if (DevelopB) { WriteLine($" 11 S ->RRnxtC[rc:{RRnxtC.rc}]#{nox} is false."); __Debug_ChainPrint(RRR); } } } } else if (RR.type == W) //---------- Check connection conditions. case WeakLink(T->F) ---------- { foreach (UCell P in RR.UGCellsB) //foreach next GLink { if ((P.FreeB & no2B) > 0) { Qfalse[no2].BPSet(P.rc); //set P.rc#no2 is true if (DevelopB) { WriteLine($" 12 W *Rad->{P} #{no2} is false."); } } } } } //====================== Radiation Search ============================================================== while (rcQue.Count > 0) { { //----- Distinct ----- var Q2 = rcQue.ToList().Distinct(); rcQue.Clear(); foreach (var X in Q2) { rcQue.Enqueue(X); } //if(DevelopB){ WriteLine(); foreach(var P in rcQue) WriteLine($"--rcQue---{P.GrLKToString()}"); WriteLine(); } } GroupedLink R = rcQue.Dequeue(); //dequeue next element(pre-GLink) if (DevelopB) { WriteLine($"\r20�� {dbX++}---Queue:" + R.GrLKToString()); __Debug_ChainPrint(R); } foreach (GroupedLink RR in IEGet_SuperLink(R).Where(p => p.AvailableF)) { if (_IsLooped(RR)) { continue; } if (R.type != RR.type && R.UGCellsA.Equals(RR.UGCellsB)) { continue; //Skip back_links } if (!(R.UsedCs & RR.UGCellsB.B81).IsZero()) { continue; } RR.preGrpedLink = R; //set preLink RR.UsedCs = R.UsedCs | RR.UGCellsB.B81; rcQue.Enqueue(RR); //enqueue next-GLink to RadiationSearchQueue if (DevelopB) { __Debug_ChainPrint(RR); WriteLine($"�� {dbX++}-{++chkX}--RR:" + RR.GrLKToString()); } int no2 = RR.no2; //no2:next digit if (RR.type == S) //========== Check connection conditions. case StrongLink(F->T) ========== //if(!(RR.UGCellsB.B81&Qtrue[RR.no2]).IsZero() ) continue; //xxx if the next element is already setted true, go to the next process { if (RR.UGCellsB.Count == 1) //if the link's next element is a single cell { UCell P = RR.UGCellsB[0]; //RRnxtC:next cell if (P.rc == rc0) //Check Loop completion { GNL_Result.resultGLK = RR; SolCode = GroupedNLEx_CheckSolution(GNL_Result, ref contDiscontF); //There are cells/#n that can be excluded. if (SolCode > 0) { goto LoopCompletion; //Established Sudoku solution } goto ErrorTrial; //Failed } if (Qtrue[no2].IsHit(P.rc)) { RR.AvailableF = false; continue; } //AvailableF=false Qtrue[no2].BPSet(P.rc); // set P.rc#no2 is true if (DevelopB) { WriteLine($" 30S ->P:{P} +#{no2} is true."); } foreach (int nox in P.FreeB.IEGet_BtoNo().Where(q => (q != no2))) // P.rc#no2:True => #nox(!=no2):False { if (Qfalse[nox].IsHit(P.rc)) { continue; } Qfalse[nox].BPSet(P.rc); //set P.rc#no2 to false if (DevelopB) { WriteLine($" 31S ->P:{P} -#{nox} is false."); } } } } else if (RR.type == W) //========== Check connection conditions. case WeakLink(T->F) ========== { if (!(RR.UGCellsB.B81 & Qfalse[RR.no2]).IsZero()) { continue; //if the next element is setted false, go to the next process } foreach (UCell P in RR.UGCellsB) //foreach next GLink { if (Qfalse[no2].IsHit(P.rc)) { continue; } Qfalse[no2].BPSet(P.rc); //set P.rc#no2 is true if (DevelopB) { WriteLine($" -40W *RR:{P} -#{no2} is false."); } } rcQue.Enqueue(RR); //enqueue next-GLink to RadiationSearchQueue if (RR.UGCellsB.Count == 1) //if the link's next element is a single cell { UCell P = RR.UGCellsB[0]; if (P.FreeBC == 2) //If the next is a binary cell { int nox = P.FreeB.DifSet(1 << no2).BitToNum(); //if(!_Check_LogicalError_GNL(no2,P.rc,Qtrue) ) goto ErrorTrial; //No check required! //if(Qtrue[nox].IsHit(P.rc)){ RR.AvailableF=false; continue; }//AvailableF=false. No check required! Qtrue[nox].BPSet(P.rc); //set P.rc#no2 is true GroupedLink RRR = new GroupedLink(P, no2, nox, S); //GLK_ViVal:GLink in cell(P#no2 StrongLink) RRR.preGrpedLink = RR; //set preLink if (DevelopB) { WriteLine($" +41W *RR:{P} -#{nox} is true. :{RRR.GrLKToString()}"); } if (P.rc == rc0) { GNL_Result.resultGLK = RR; SolCode = GroupedNLEx_CheckSolution(GNL_Result, ref contDiscontF); if (SolCode > 0) { goto LoopCompletion; //Solution found } goto ErrorTrial; } } } } } } return(null); ErrorTrial: return(null); LoopCompletion: GNL_Result.contDiscontF = contDiscontF; if (DevelopB) { L2SprLkB81[no0].BPSet(rc0); // Set the searched flag if (DevelopB) { developDisp(rc0, no0, GNL_Result, DevelopB); } L2SprLK[rc0, no0] = GNL_Result; } return(GNL_Result); } catch (Exception ex) { WriteLine($"{ex.Message}+\r{ex.StackTrace}"); } return(null); }
//W-Wing is an algorithm composed of bivalue cell and link. //http://csdenpe.web.fc2.com/page43.html public bool Wwing( ) { Prepare(); CeLKMan.PrepareCellLink(1); //Generate StrongLink if (BVCellLst == null) { BVCellLst = pBDL.FindAll(p => (p.FreeBC == 2)); //BV:BiValue } if (BVCellLst.Count < 2) { return(false); } BVCellLst.Sort((A, B) => (A.FreeB - B.FreeB)); //Important!!! bool Wwing = false; var cmb = new Combination(BVCellLst.Count, 2); int nxt = 99; while (cmb.Successor(nxt)) { UCell P = BVCellLst[cmb.Index[0]]; UCell Q = BVCellLst[cmb.Index[1]]; nxt = 1; if (P.FreeB != Q.FreeB) { nxt = 0; continue; } //BVCellLst is sorted, so possible to skip. if (ConnectedCells[P.rc].IsHit(Q.rc)) { continue; } foreach (var L in CeLKMan.IEGetCellInHouse(1)) //1:StrongLink(Link has a direction. The opposite link is different.) { int no1B = (1 << L.no); if ((P.FreeB & no1B) == 0) { continue; } if (L.rc1 == P.rc || L.rc2 == Q.rc) { continue; } if (!ConnectedCells[P.rc].IsHit(L.rc1)) { continue; //L.rc1 is in the connected area of P.rc? } if (!ConnectedCells[Q.rc].IsHit(L.rc2)) { continue; //L.rc2 is in the connected area of Q.rc? } int no2B = P.FreeB.BitReset(L.no); //another digit string msg2 = ""; Bit81 ELM = ConnectedCells[P.rc] & ConnectedCells[Q.rc]; //ELM:Common part of the influence area of cell P and cell Q foreach (var E in ELM.IEGetUCeNoB(pBDL, no2B)) //Cell/digit in ELM can be excluded { E.CancelB = no2B; Wwing = true; //W-Wing found if (SolInfoB) { msg2 += " " + E.rc.ToRCString(); } } if (!Wwing) { continue; } SolCode = 2; if (SolInfoB) { UCell A = pBDL[L.rc1], B = pBDL[L.rc2]; int noBX = P.FreeB.DifSet(no2B); P.SetNoBBgColor(noBX, AttCr, SolBkCr2); Q.SetNoBBgColor(noBX, AttCr, SolBkCr2); A.SetNoBBgColor(no1B, AttCr, SolBkCr); B.SetNoBBgColor(no1B, AttCr, SolBkCr); string msg0 = $" bvCell: {_XYwingResSub(P)} ,{_XYwingResSub(Q)}"; string msg1 = $" SLink: {A.rc.ToRCNCLString()}-{B.rc.ToRCNCLString()}(#{(L.no+1)})"; Result = $"W Wing Eli.;#{(no2B.BitToNum()+1)} in {msg2.ToString_SameHouseComp()}"; ResultLong = "W Wing\r" + msg0 + "\r" + msg1 + $"\r Eliminated: #{(no2B.BitToNum()+1)} in {msg2.ToString_SameHouseComp()}"; } if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } Wwing = false; } } return(false); }
public IEnumerable <UBasCov> IEGet_BaseSet(int sz, int rnk) { if (UGLLst == null) { yield break; } __checkCC = 0; List <UGLink> basUGLs = new List <UGLink>(); Bit981 HB981 = new Bit981(); //BaseSet bitPattern Bit324 usedLK = new Bit324(); //usedLink(by serial number) List <int> usedLKLst = new List <int>(); Bit81Chk coverChk = new Bit81Chk(sz, rnk, basUGLs, usedLKLst, usedLKIgnrLst); var cmbBas = new Combination(UGLLst.Count, sz); long rcbn36 = 0; int jkC = 0; int nxt = int.MaxValue; //(skip function) while (cmbBas.Successor(nxt)) { GeneralLogicGen.ChkBas1++; //***** jkC++; //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* sz=1 if (sz == 1) { UGLink UGL = UGLLst[cmbBas.Index[0]]; if (UGL.UC is UCell) { goto LNextSet; // if size=1, cell-type is invalid } // UGL.rcBit81 is Bit81 int blkB = (int)UGL.Get_rcbnFrame(2); if (blkB.BitCount() > 1) { goto LNextSet; } int no = UGL.rcBit81.no, b = blkB.BitToNum(); var P = UGLLst.Find(U => U.Equal_no_block(no, b)); if (P == null) { goto LNextSet; } if ((P.rcBit81 - UGL.rcBit81).Count == 0) { goto LNextSet; } //there are numbers only within one block HB981.Clear(); HB981.BPSet(UGL.rcBit81.no, UGL.rcBit81, tfbSet: false); basUGLs.Clear(); basUGLs.Add(UGL); GeneralLogicGen.ChkBas2++; //***** goto LBSFound; //possibility of solution } //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* sz>=2 HB981.Clear(); basUGLs.Clear(); usedLKLst.Clear(); coverChk.Clear(); rcbn36 = 0; //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2 for (int k = 0; k < sz; k++) { nxt = k; UGLink UGL = UGLLst[cmbBas.Index[k]]; rcbn36 |= UGL.rcbnFrame2; if (!Check_rcbnCondition(sz, rnk, k, rcbn36)) { goto LNextSet; //# Extremely efficient } if (UGL.rcBit81 is Bit81) // ............ rcb ............ { if (k > 0 && HB981.IsHit(UGL.rcBit81.no, UGL.rcBit81)) { goto LNextSet; //included in BaseSet } HB981.BPSet(UGL.rcBit81.no, UGL.rcBit81, tfbSet: true); //register to BaseSet usedLKLst.Add(UGL.rcBit81.ID); //tfx<<4 | no int no = UGL.rcBit81.no; coverChk.noB |= 1 << no; //qq } else // ........... Cell ............ { UCell UC = UGL.UC; int rc = UC.rc; foreach (var n in UC.FreeB.IEGet_BtoNo(9)) { if (k > 0 && HB981.IsHit(n, rc)) { goto LNextSet; } HB981.BPSet(n, rc, tfbSet: true); } int IDrc = rc << 17 | 1 << 16; usedLKLst.Add(IDrc); //tfx<<4 | no } basUGLs.Add(UGL); //qq } GeneralLogicGen.ChkBas2++; //***** bool niceB = coverChk.Check_BaseSetCondition(HB981); //########## check_rcB9 ########## if (!niceB) { goto LNextSet; } //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2 if (sz >= 2) { int noBP = HB981.nzBit; int noCC = noBP.BitCount(); if (noCC >= 2) { List <int> IX = noBP.IEGet_BtoNo().ToList(); if (sz >= 2) { for (int k = 0; k < noCC; k++) { Bit81 A = new Bit81(), B = new Bit81(); int no = IX[k]; foreach (var P in basUGLs) { if (P.rcBit81 is Bit81) { if (P.rcBit81.no == no) { A |= P.rcBit81; } else { B |= P.rcBit81; } } else { int rc = P.UC.rc; foreach (var n in P.UC.FreeB.IEGet_BtoNo()) { if (n == no) { A.BPSet(rc); } else { B.BPSet(rc); } } } } int nOL = (B & A).Count; if (rnk == 0 && nOL < 2) { goto LNextSet; } if (rnk > 0 && nOL < 1) { goto LNextSet; } // WriteLine("---------- no:{0} sz:{1} rnk:{2} nOL:{3} (A-B):{4} (B-A):{5}", no, sz,rnk, nOL, (A-B).Count, (B-A).Count ); } //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2 } } } //--------------------------------------------------------------------------------------- LBSFound: if (SDK_Ctrl.UGPMan.stageNo == 12 && sz >= 3)// && rnk==1 ){ { WriteLine("\r sz:{0} rnk:{1} jkc:{2}", sz, rnk, jkC); Check_rcbnCondition(sz, rnk, sz, rcbn36, printB: true); basUGLs.ForEach(P => WriteLine(P.ToString("BaseSet"))); } usedLK.Clear(); basUGLs.ForEach(P => usedLK.BPSet(P.SrNum)); //IDrc: rc<<17 | 1<<16 UBasCov UBC = new UBasCov(basUGLs, HB981, sz, usedLK); yield return(UBC); LNextSet: continue; } yield break; }