//============================================================================================================ public bool GenMessage2(USuperLink USLK, UCell P, int no) { var pQtrue = USLK.Qtrue; var pQfalse = USLK.Qfalse; if (!pQfalse[no].IsHit(P.rc) || !pQtrue[no].IsHit(P.rc)) { return(false); } var pchainDesLKT = USLK.chainDesLKT; //■ var pchainDesLKF = USLK.chainDesLKF; //□ GroupedLink Pdes = (GroupedLink)pchainDesLKT[P.rc, no]; //■ string st = ""; if (Pdes != null) { st += " " + _chainToString2(P, Pdes, -(no + 1)); //■_chainToString2 } Pdes = (GroupedLink)pchainDesLKF[P.rc, no]; //□ if (Pdes != null) { if (st.Length > 4) { st += "\r"; } else { st = ""; } st += " " + _chainToString2(P, Pdes, no + 1); //■_chainToString2 } USLK.stMsg = st; return(true); }
private void _LinkSearch(bool printSW = false) { int IDx = -1; // *==* cell-cell link for (int no = 0; no < 9; no++) { for (int tfx = 0; tfx < 27; tfx++) { int noB = 1 << no; List <UCell> PLst = pBDL.IEGetCellInHouse(tfx, noB).ToList(); int szL = PLst.Count; if (szL <= 1) { continue; } int SW = (szL == 2)? 0: 1; IDx++; var LK1 = new UGLink_unit(IDx, SW, tfx, no, PLst); GLK_UList_All.Add(LK1); Combination cmb = new Combination(szL, 2); while (cmb.Successor()) { UCell UC1 = PLst[cmb.Index[0]], UC2 = PLst[cmb.Index[1]]; __SetGLinkLstSet(LK1, SW, tfx, no, UC1, UC2); } } } // *==* in-cell link foreach (var P in pBDL.Where(p => p.No == 0)) { int rc = P.rc; int[] noLst = P.FreeB.IEGet_BtoNo().ToArray(); int szL = noLst.Length; if (szL <= 1) { continue; } int SW = (szL == 2)? 0: 1; IDx++; var LK2 = new UGLink_unit(IDx, SW, rc, P.FreeB); GLK_UList_All.Add(LK2); Combination cmb = new Combination(szL, 2); while (cmb.Successor()) { int no1 = noLst[cmb.Index[0]], no2 = noLst[cmb.Index[1]]; __SetGLinkLstSet(LK2, SW, rc, no1, no2); } } if (printSW) { WriteLine($"============================ stage:{stageNo} GLK_UList_All"); foreach (var P in GLK_UList_All) { WriteLine(P); } WriteLine($"============================ stage:{stageNo} GLK_connection"); foreach (var rc in Enumerable.Range(0, 81)) { foreach (var no in Enumerable.Range(0, 9)) { if (GLK_connection[rc, no] != null) { GLK_connection[rc, no].ForEach(P => WriteLine(P.ToString_rcno(rc, no))); } } } } }
//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 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 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 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; }
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 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]]); }
//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); }
//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("\r"); foreach(var P in rcQue) WriteLine($"--rcQue---{P.GrLKToString()}"); WriteLine("\r"); } } 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); }
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("\r"); foreach(var P in rcQue) WriteLine($"--rcQue---{P.GrLKToString()}"); WriteLine("\r"); } } 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); }
public UCellLink(UCell UCe1, UCell UCe2, int no, int type) { this.UCe1 = UCe1; this.UCe2 = UCe2; this.no = no; this.type = type; }
private void __SetGLinkLstSet(UGLink_unit LKx, int SW, int tfx, int no, UCell UC1, UCell UC2) // cell-cell link { int rc1 = UC1.rc, rc2 = UC2.rc; UGLink_pair LK1 = new UGLink_pair(LKx, SW, rc2, no); if (GLK_connection[rc1, no] == null) { GLK_connection[rc1, no] = new List <UGLink_pair>(); } GLK_connection[rc1, no].Add(LK1); UGLink_pair LK2 = new UGLink_pair(LKx, SW, rc1, no); if (GLK_connection[rc2, no] == null) { GLK_connection[rc2, no] = new List <UGLink_pair>(); } GLK_connection[rc2, no].Add(LK2); }
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) } }
//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); }
//##### There is a bug ##### public USuperLink Eval_SuperLinkChain(int rc0, int no0, bool Gbreak, int typeSel, bool DevelopB) { // rc0: start cell's rc index // no0: start digit // Gbreak(bool): T:If the evaluation values are inconsistent, the search is suspended. // typeSel(int): Start link type1 1:Strong 2:Weak 3:S+W 0:- 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; #region stsrt 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 } } } } #endregion stsrt #region Radial Search //====================== Radial 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 } } } } GLKH.GenNo = R.GenNo + 1; rcQue.Enqueue(GLKH); //enqueue next-GLink to RadiationSearchQueue } } #endregion Radial Search 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 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); */ }
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); }