private IEnumerable <Bit81[]> _RPColoring( ) { if (BVCellLst.Count < 4) { yield break; } Bit81 TBD = new Bit81(); BVCellLst.ForEach(p => TBD.BPSet(p.rc)); int rc1; while ((rc1 = TBD.FindFirstrc()) >= 0) { Bit81[] CRL = new Bit81[2]; CRL[0] = new Bit81(); CRL[1] = new Bit81(); Queue <int> rcQue = new Queue <int>(); rcQue.Enqueue(rc1 << 1); CRL[0].BPSet(rc1); int FreeB = pBDL[rc1].FreeB; CRL[0].ID = FreeB; while (rcQue.Count > 0) { int rcX = rcQue.Dequeue(); int kx = 1 - (rcX & 1); rc1 = rcX >> 1; TBD.BPReset(rc1); Bit81 Chain = TBD & ConnectedCells[rc1]; foreach (var rc2 in Chain.IEGet_rc()) { if (!TBD.IsHit(rc2)) { continue; } if (pBDL[rc2].FreeB != FreeB) { continue; } rcQue.Enqueue((rc2 << 1) | kx); CRL[kx].BPSet(rc2); TBD.BPReset(rc2); } } yield return(CRL); } yield break; }
static public Bit81[] HouseCells; //Row(0-8) Collumn(9-17) Block(18-26) static private void Create_ConnectedCells() { if (ConnectedCells != null) { return; } ConnectedCells = new Bit81[81]; //ConnectedCellsRev = new Bit81[81]; for (int rc = 0; rc < 81; rc++) { Bit81 BS = new Bit81(); foreach (var q in __IEGetCellsConnectedRC(rc).Where(q => q != rc)) { BS.BPSet(q); } BS.BPReset(rc); ConnectedCells[rc] = BS; //ConnectedCellsRev[rc] = BS ^ 0x7FFFFFF; } HouseCells = new Bit81[27]; for (int tfx = 0; tfx < 27; tfx++) { Bit81 tmp = new Bit81(); foreach (var q in __IEGetCellInHouse(tfx)) { tmp.BPSet(q); } HouseCells[tfx] = tmp; } }
private IEnumerable <Bit81[]> _Coloring(int no) { Bit81[] CRL = new Bit81[2]; CRL[0] = new Bit81(); CRL[1] = new Bit81(); Bit81 TBD = new Bit81(pBDL, (1 << no)); int rc1 = TBD.FindFirstrc(); while (rc1 >= 0) { Queue <int> rcQue = new Queue <int>(); rcQue.Enqueue(rc1 << 1); CRL[0].BPSet(rc1); TBD.BPReset(rc1); while (rcQue.Count > 0) { rc1 = rcQue.Dequeue(); int kx = 1 - (rc1 & 1); rc1 >>= 1; TBD.BPReset(rc1); foreach (var P in CeLKMan.IEGetRcNoType(rc1, no, 1)) { int rc2 = P.rc2; if (!(CRL[0] | CRL[1]).IsHit(rc2) && TBD.IsHit(rc2)) { CRL[kx].BPSet(rc2); rcQue.Enqueue((rc2 << 1) | kx); } } } yield return(CRL); if ((rc1 = TBD.FindFirstrc()) < 0) { yield break; } CRL = new Bit81[2]; CRL[0] = new Bit81(); CRL[1] = new Bit81(); } yield break; }
private IEnumerable <Bit81[]> _GetXChain(int no, List <int> LKRec) { Bit81 TBD = new Bit81(pBDL, (1 << no)); int rcS; while ((rcS = TBD.FindFirstrc()) >= 0) //rcS:Set the origin cell. { TBD.BPReset(rcS); //Reset TBD to Processed. //===== Repeatedly coloring processing. initialize ===== Bit81[] CRL = new Bit81[3]; //Coloring 2 groups(CRL[0] and CRL[1]). CRL[0] = new Bit81(); CRL[1] = new Bit81(rcS); CRL[2] = new Bit81(); CRL[0].ID = rcS; Queue <int> rcQue = new Queue <int>(); rcQue.Enqueue((rcS << 1) | 1); //(First StrongLink) //===== Repeatedly coloring processing. start ===== LKRec.Clear(); //clear chain recorder. bool firstLK = true; while (rcQue.Count > 0) { int rcX = rcQue.Dequeue(); //recorded [cell and color] int swF = 1 - (rcX & 1); //next color(inversion S-W) int rc1 = (rcX >> 1); //next cell foreach (var LKx in CeLKMan.IEGetRcNoType(rc1, no, (swF + 1))) //LKx:link connected to cell rc1 { int rc2 = LKx.rc2; //anather cell of LKx if ((CRL[0] | CRL[1]).IsHit(rc2)) { continue; //already colored } CRL[swF].BPSet(rc2); //coloring rcQue.Enqueue((rc2 << 1) | swF); //enqueue(next cell and color) LKRec.Add(rc1 << 8 | rc2); //chain record if (firstLK) { CRL[2].BPSet(rc2); //record colored cells from rcS(source cell) } } firstLK = false; } if (CRL[1].Count > 0) { yield return(CRL); } //----- Repeatedly coloring processing. end ----- } yield break; }
//XY-Chain is an algorithm using Locked which occurs in the concatenation of bivalues. //http://csdenpe.web.fc2.com/page49.html public bool XYChain() { Prepare(); CeLKMan.PrepareCellLink(1); //Generate StrongLink List <int> LKRec = new List <int>(); foreach (var CRL in _GetXYChain(LKRec)) { int rcS = CRL[0].ID, no = CRL[1].ID, noB = (1 << no); Bit81 ELM = ConnectedCells[rcS] - (CRL[0] | CRL[1]); if (ELM.IsZero()) { continue; } Bit81 ELM2 = new Bit81(); bool XYChainF = false; foreach (var E in ELM.IEGetUCeNoB(pBDL, noB)) { if (CRL[0].IsHit(ConnectedCells[E.rc])) { E.CancelB = noB; XYChainF = true; ELM2 |= CRL[0] & ConnectedCells[E.rc]; break; } } if (!XYChainF) { continue; } //===== XY-Chain found ===== SolCode = 2; String SolMsg = "XY Chain"; Result = SolMsg; int rcE; foreach (var P in ELM2.IEGetUCeNoB(pBDL, noB)) { P.SetNoBBgColor(noB, AttCr, SolBkCr); } Bit81 ELM2cpy = ELM2.Copy(); while ((rcE = ELM2.FindFirstrc()) >= 0) { string stR = ""; Bit81 XYchainB = _SelectLink_XYChain(LKRec, rcS, rcE, noB, ref stR) - ELM2cpy; if (SolInfoB) { SolMsg += "\r " + stR; } foreach (var P in XYchainB.IEGetUCeNoB(pBDL, 0x1FF)) { P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr2); } ELM2.BPReset(rcE); } if (SolInfoB) { ResultLong = SolMsg; } pBDL[rcS].SetNoBBgColor(noB, AttCr, SolBkCr); if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } XYChainF = false; } return(false); }
} //UVWXYZ-wing private bool _UVWXYZwing(int wsz) //simple UVWXYZwing { if (pAnMan.GStage != GStageMemo) { GStageMemo = pAnMan.GStage; FBCX = pBDL.FindAll(p => p.FreeBC == wsz); } if (FBCX.Count == 0) { return(false); } bool wingF = false; foreach (var P0 in FBCX) //focused Cell { int b0 = P0.b; //focused Block foreach (int no in P0.FreeB.IEGet_BtoNo()) //focused Digit { int noB = 1 << no; Bit81 P0con = (new Bit81(pBDL, noB, FreeBC: 2)) & ConnectedCells[P0.rc]; Bit81 Pin = P0con & HouseCells[18 + P0.b]; Bit81 Pout = null, Pin2 = null; for (int dir = 0; dir < 2; dir++) //dir 0:row 1:col { int rcDir = (dir == 0)? P0.r: (9 + P0.c); Pin2 = Pin - HouseCells[rcDir]; if (Pin2.IsZero()) { continue; } Pout = (P0con & HouseCells[rcDir]) - HouseCells[18 + P0.b]; if (Pin2.Count + Pout.Count != (wsz - 1)) { continue; } int FreeBin = Pin2.AggregateFreeB(pBDL); int FreeBout = Pout.AggregateFreeB(pBDL); if ((FreeBin | FreeBout) != P0.FreeB) { continue; } Bit81 ELst = HouseCells[rcDir] & HouseCells[18 + P0.b]; ELst.BPReset(P0.rc); string msg3 = ""; foreach (var E in ELst.IEGet_rc().Select(p => pBDL[p])) { if ((E.FreeB & noB) > 0) { E.CancelB = noB; wingF = true; msg3 += " " + E.rc.ToRCString(); } } if (!wingF) { continue; } //--- ...wing found ------------- SolCode = 2; string[] xyzWingName = { "XYZ-Wing", "WXYZ-Wing", "VWXYZ-Wing", "UVWXYZ-Wing" }; string SolMsg = xyzWingName[wsz - 3]; if (SolInfoB) { P0.SetNoBBgColor(P0.FreeB, AttCr, SolBkCr2); foreach (var P in Pin2.IEGet_rc().Select(p => pBDL[p])) { P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr); } foreach (var P in Pout.IEGet_rc().Select(p => pBDL[p])) { P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr); } string msg0 = " Pivot: " + P0.rc.ToRCString(); string st = ""; foreach (var rc in Pin2.IEGet_rc()) { st += " " + rc.ToRCString(); } string msg1 = " in: " + st.ToString_SameHouseComp(); st = ""; foreach (var rc in Pout.IEGet_rc()) { st += " " + rc.ToRCString(); } string msg2 = " out: " + st.ToString_SameHouseComp(); st = ""; foreach (var rc in Pin2.IEGet_rc()) { st += " " + rc.ToRCString(); } ResultLong = SolMsg + "\r" + msg0 + "\r " + msg1 + "\r " + msg2 + "\r Eliminated: " + msg3.ToString_SameHouseComp(); Result = SolMsg + msg0 + msg1 + msg2; } if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } wingF = false; } } } return(false); }
public bool Check_BaseSetCondition(Bit981 HB981) //for sz>=2 { bool niceB = false, E = false; jkC++; #region There is a link between the link and the other link group for (int k = 0; k < sz; k++) { UGLink UGL = basUGLs[k]; Bit981 Bcum = new Bit981(); for (int m = 0; m < sz; m++) { if (m == k) { continue; } Bcum |= basUGLs[m].rcbn2; } if ((Bcum & UGL.rcbn_conn2).Count <= 0) { goto Lreturn; //false } } #endregion GeneralLogicGen.ChkBas3++; //***** #region Every element of the number(#no) has a link //それぞれのリンクは、その他のリンク群と連結する。 //リンクしないセルはrnk個数以下でなければならない。 //if(E) for(int n=0; n<9; n++ ) WriteLine(HB981.tfx27Lst[n].ToBitString(27)); Bit981 Q9 = HB981.Copy(); usedLKLst.ForEach(p => HB981.tfxReset(p & 0xF, p >> 4)); usedLKIgnrLst.ForEach(p => HB981.tfxReset(p & 0xF, p >> 4)); //if(E) for(int n=0; n<9; n++ ) WriteLine(HB981.tfx27Lst[n].ToBitString(27)); int QPP = 0; foreach (var no in noB.IEGet_BtoNo()) { Bit81 Q = Q9._BQ[no];//new Bit81(HB981._BQ[no]); //if(E) WriteLine( "HB981.tfxLst[no]: "+HB981.tfx27Lst[no].ToBitString(27) ); foreach (var tfx in HB981.tfx27Lst[no].IEGet_tfb()) { int bp = HB981.GetBitPattern_tfnx(no, tfx); if (bp <= 0) { continue; } int nc = bp.BitCount(); if (nc >= 2) { if (E) { WriteLine("Q: " + Q.ToString()); } foreach (var nx in bp.IEGet_BtoNo()) { int rc = tfx.Get_tfx_rc(nx); Q.BPReset(rc); } //if(E) WriteLine("Q: "+Q.ToString() ); } } QPP += Q.Count; } if (QPP <= rnk) { niceB = true; goto Lreturn; } #endregion GeneralLogicGen.ChkBas3++; //***** #region There is a possibility link between the patterns of numbers n1,n2 //数字間のリンクしないセルは、rnk*2以下でなければならない。 if (HB981.nzBit.BitCount() >= 2) { bool firstB = true; Bit81 Q = null; foreach (var n in HB981.nzBit.IEGet_BtoNo()) { if (firstB) { Q = HB981._BQ[n]; firstB = false; } else { Q |= HB981._BQ[n]; } } foreach (var rc in Q.IEGetRC()) { if (HB981.GetBitPattern_rcN(rc).BitCount() >= 2) //セルrcの数字間リンクがあるときは、Q9リセット { foreach (var no in noB.IEGet_BtoNo()) { Q9._BQ[no].BPReset(rc); } } } int Q9cc = Q9.BitCount(); if (Q9cc <= rnk) { niceB = true; goto Lreturn; } //直接リンクしないセルがrnk以下のときは、次のテストに進む if (Q9cc <= rnk * 2) { GeneralLogicGen.ChkBas1B++; //***** foreach (var n1 in Q9.nzBit.IEGet_BtoNo()) { foreach (var rc in Q9._BQ[n1].IEGetRC()) { foreach (var n2 in Q9.nzBit.IEGet_BtoNo().Where(nx => nx != n1)) { if ((Q9._BQ[n2] & p_connectedCells[rc]).BitCount() == 0) { continue; } //リンクしないセル間を繋ぐリンクがある(”可能性あり”で次のテストに進む GeneralLogicGen.ChkBas1A++; //***** niceB = true; goto Lreturn; } } } } } #endregion GeneralLogicGen.ChkBas4++; //***** Lreturn: return(niceB); }