//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); }
public USuperLink CTD_EvalSuperLinkChain(UCell P0, int no0, bool DevelopB = false) { try{ int dbX = 0, rc0 = P0.rc; _dbCC = 0; if (DevelopB) { WriteLine($"\r\r10 *Origin rc0:{rc0} no0:{no0}"); } 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>(); //===== First GLK Process ===== foreach (GroupedLink R in IEGet_SuperLinkFirst(P0, no0).Where(p => p.type == W)) { rcQue.Enqueue(R); //Enqueue first GLK } //====================== 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 = Contradiction_CheckSolution(GNL_Result); //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 = Contradiction_CheckSolution(GNL_Result); if (SolCode > 0) { goto LoopCompletion; //Solution found } goto ErrorTrial; } } } } } } return(null); ErrorTrial: return(null); LoopCompletion: GNL_Result.contDiscontF = 999999999; ////// 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); }