public string __Debug_ChainPrint(GroupedLink P, bool PrintOn = true) { GroupedLink Q = P; string st = ""; if (Q == null) { st += "null"; } else { int nc = 0; do { st = Q.GrLKToString() + st; Q = Q.preGrpedLink as GroupedLink; if (Q == null) { break; } st = " Бб " + st; if (++nc > 20) { break; } }while(true); } st = $"\tБЯ{++_dbCC}БЯ{st}"; if (P.UGCellsB.B81.Count == 1) { st += "БЬБЬБЬ"; } if (PrintOn) { WriteLine(st); } return(st); }
//##### 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); }
//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); }