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 = new Bit81(ELM2); 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); }
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) } }
} //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); }