public Bit981(UGLink UGL) : this() { Bit981 B = new Bit981(); if (UGL.rcBit81 is Bit81) { int no = UGL.rcBit81.no; B._BQ[no] = UGL.rcBit81; foreach (int rc in UGL.rcBit81.IEGet_rc()) { B._BQ[no].BPSet(rc); } if (!UGL.rcBit81.IsZero()) { nzBit |= (1 << no); } } else { UCell uc = UGL.UC as UCell; foreach (var n in uc.FreeB.IEGet_BtoNo()) { B._BQ[n].BPSet(uc.rc); nzBit |= (1 << n); } } }
public Bit981(Bit981 Q) : this() { this.nzBit = Q.nzBit; for (int n = 0; n < sz; n++) { this._BQ[n] = Q._BQ[n]; } }
public uint CompareTo(Bit981 B) { for (int n = 0; n < sz - 1; n++) { if (this._BQ[n] == B._BQ[n]) { return((uint)(this._BQ[n].CompareTo(B._BQ[n]))); } } return((uint)(this._BQ[sz - 1].CompareTo(B._BQ[sz - 1]))); }
static public Bit981 operator-(Bit981 A, Bit981 B) { Bit981 C = new Bit981(); for (int n = 0; n < sz; n++) { C._BQ[n] = A._BQ[n] - B._BQ[n]; } __Set_nzBit(C); return(C); }
public Bit981 Copy() { Bit981 Scpy = new Bit981(); for (int n = 0; n < sz; n++) { Scpy._BQ[n] = _BQ[n].Copy(); } Scpy.nzBit = this.nzBit; return(Scpy); }
public override bool Equals(object obj) { Bit981 A = obj as Bit981; if (A == null) { return(false); } for (int k = 0; k < sz; k++) { if (_BQ[k] != A._BQ[k]) { return(false); } } return(true); }
static private void __Set_nzBit(Bit981 C) { int nzBit = 0; for (int n = 0; n < sz; n++) { if (C._BQ[n].IsZero()) { nzBit &= ((1 << n) ^ 0x7FFFFFFF); } else { nzBit |= (1 << n); } } C.nzBit = nzBit; }
public UGLink(UCell UC) { this.SrNum = SrNum0++; this.UC = UC; rcbn2 = new Bit981(); rcbn_conn2 = new Bit981(); foreach (var n in UC.FreeB.IEGet_BtoNo()) { rcbn2.BPSet(n, UC.rc); } for (int n = 0; n < 9; n++) { rcbn_conn2._BQ[n] |= p_connectedCells[UC.rc]; } int _rcbFrame = (1 << UC.r | 1 << (UC.c + 9) | 1 << (UC.b + 18)); rcbnFrame2 = (long)_rcbFrame | ((long)UC.FreeB) << 27; //■ }
public bool Check_connected(Bit981 HB981) { if (rcBit81 is Bit81) { int no = rcBit81.no; return(HB981._BQ[no].IsHit(rcbn_conn2._BQ[no])); } else { int rc = UC.rc; foreach (var n in UC.FreeB.IEGet_BtoNo()) { if (HB981._BQ[n].IsHit(rc)) { return(true); } } return(false); } }
public UGLink(Bit81 rcBit81) { this.SrNum = SrNum0++; this.rcBit81 = rcBit81; this.sz = rcBit81.BitCount(); rcbn2 = new Bit981(rcBit81); rcbn_conn2 = new Bit981(); var _conn = new Bit81(); foreach (var rc in rcBit81.IEGet_rc()) { _conn |= p_connectedCells[rc]; for (int n = 0; n < 9; n++) { rcbn_conn2.BPSet(n, rc); } } int no = rcBit81.no; rcbn_conn2._BQ[no] = _conn - rcBit81; rcbnFrame2 = (long)rcBit81.Get_RowColumnBlock() | ((long)1 << (no + 27)); //■ }
public IEnumerable <UBasCov> IEGet_BaseSet(int sz, int rnk) { if (UGLLst == null) { yield break; } __checkCC = 0; List <UGLink> basUGLs = new List <UGLink>(); Bit981 HB981 = new Bit981(); //BaseSet bitPattern Bit324 usedLK = new Bit324(); //usedLink(by serial number) List <int> usedLKLst = new List <int>(); Bit81Chk coverChk = new Bit81Chk(sz, rnk, basUGLs, usedLKLst, usedLKIgnrLst); var cmbBas = new Combination(UGLLst.Count, sz); long rcbn36 = 0; int jkC = 0; int nxt = int.MaxValue; //(skip function) while (cmbBas.Successor(nxt)) { GeneralLogicGen.ChkBas1++; //***** jkC++; //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* sz=1 if (sz == 1) { UGLink UGL = UGLLst[cmbBas.Index[0]]; if (UGL.UC is UCell) { goto LNextSet; // if size=1, cell-type is invalid } // UGL.rcBit81 is Bit81 int blkB = (int)UGL.Get_rcbnFrame(2); if (blkB.BitCount() > 1) { goto LNextSet; } int no = UGL.rcBit81.no, b = blkB.BitToNum(); var P = UGLLst.Find(U => U.Equal_no_block(no, b)); if (P == null) { goto LNextSet; } if ((P.rcBit81 - UGL.rcBit81).Count == 0) { goto LNextSet; } //there are numbers only within one block HB981.Clear(); HB981.BPSet(UGL.rcBit81.no, UGL.rcBit81, tfbSet: false); basUGLs.Clear(); basUGLs.Add(UGL); GeneralLogicGen.ChkBas2++; //***** goto LBSFound; //possibility of solution } //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* sz>=2 HB981.Clear(); basUGLs.Clear(); usedLKLst.Clear(); coverChk.Clear(); rcbn36 = 0; //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2 for (int k = 0; k < sz; k++) { nxt = k; UGLink UGL = UGLLst[cmbBas.Index[k]]; rcbn36 |= UGL.rcbnFrame2; if (!Check_rcbnCondition(sz, rnk, k, rcbn36)) { goto LNextSet; //# Extremely efficient } if (UGL.rcBit81 is Bit81) // ............ rcb ............ { if (k > 0 && HB981.IsHit(UGL.rcBit81.no, UGL.rcBit81)) { goto LNextSet; //included in BaseSet } HB981.BPSet(UGL.rcBit81.no, UGL.rcBit81, tfbSet: true); //register to BaseSet usedLKLst.Add(UGL.rcBit81.ID); //tfx<<4 | no int no = UGL.rcBit81.no; coverChk.noB |= 1 << no; //qq } else // ........... Cell ............ { UCell UC = UGL.UC; int rc = UC.rc; foreach (var n in UC.FreeB.IEGet_BtoNo(9)) { if (k > 0 && HB981.IsHit(n, rc)) { goto LNextSet; } HB981.BPSet(n, rc, tfbSet: true); } int IDrc = rc << 17 | 1 << 16; usedLKLst.Add(IDrc); //tfx<<4 | no } basUGLs.Add(UGL); //qq } GeneralLogicGen.ChkBas2++; //***** bool niceB = coverChk.Check_BaseSetCondition(HB981); //########## check_rcB9 ########## if (!niceB) { goto LNextSet; } //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2 if (sz >= 2) { int noBP = HB981.nzBit; int noCC = noBP.BitCount(); if (noCC >= 2) { List <int> IX = noBP.IEGet_BtoNo().ToList(); if (sz >= 2) { for (int k = 0; k < noCC; k++) { Bit81 A = new Bit81(), B = new Bit81(); int no = IX[k]; foreach (var P in basUGLs) { if (P.rcBit81 is Bit81) { if (P.rcBit81.no == no) { A |= P.rcBit81; } else { B |= P.rcBit81; } } else { int rc = P.UC.rc; foreach (var n in P.UC.FreeB.IEGet_BtoNo()) { if (n == no) { A.BPSet(rc); } else { B.BPSet(rc); } } } } int nOL = (B & A).Count; if (rnk == 0 && nOL < 2) { goto LNextSet; } if (rnk > 0 && nOL < 1) { goto LNextSet; } // WriteLine("---------- no:{0} sz:{1} rnk:{2} nOL:{3} (A-B):{4} (B-A):{5}", no, sz,rnk, nOL, (A-B).Count, (B-A).Count ); } //1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2 } } } //--------------------------------------------------------------------------------------- LBSFound: if (SDK_Ctrl.UGPMan.stageNo == 12 && sz >= 3)// && rnk==1 ){ { WriteLine("\r sz:{0} rnk:{1} jkc:{2}", sz, rnk, jkC); Check_rcbnCondition(sz, rnk, sz, rcbn36, printB: true); basUGLs.ForEach(P => WriteLine(P.ToString("BaseSet"))); } usedLK.Clear(); basUGLs.ForEach(P => usedLK.BPSet(P.SrNum)); //IDrc: rc<<17 | 1<<16 UBasCov UBC = new UBasCov(basUGLs, HB981, sz, usedLK); yield return(UBC); LNextSet: continue; } yield break; }
public void addCoverSet(List <UGLink> covUGLs, Bit981 HC981, Bit981 Can981, int rnk) { this.covUGLs = covUGLs; this.HC981 = HC981; this.Can981 = Can981; this.rnk = rnk; }
public UBasCov(List <UGLink> basUGLs, Bit981 HB981, int sz, Bit324 usedLK) { this.basUGLs = basUGLs; this.HB981 = HB981; this.sz = sz; this.usedLK = usedLK; }
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); }
//1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2 public IEnumerable <UBasCov> IEGet_CoverSet(UBasCov UBC, int rnk) { if (UGLLst == null) { yield break; } List <UGLink> basUGLs = UBC.basUGLs; Bit981 HB981 = UBC.HB981; Bit324 usedLK = UBC.usedLK; int nzBit = HB981.nzBit; int nzBitCC = nzBit.BitCount(); int sz = UBC.sz; List <UGLink> UGLCovLst = new List <UGLink>(); // UGLCovLst:candidate link #region Create UGLCovLst Bit81 Bcmp = HB981.CompressToHitCells(); foreach (var P in UGLLst.Where(q => !usedLK.IsHit(q.SrNum))) { if (P.rcBit81 is Bit81) //Row, column, block link { if ((nzBit & (1 << P.rcBit81.no)) == 0) { continue; } int B = (HB981._BQ[P.rcBit81.no] & P.rcBit81).BitCount(); if (B == 0) { continue; } // if rank:0, the CoverSet has two or more common items if (rnk == 0 && (HB981._BQ[P.rcBit81.no] & P.rcBit81).Count < 2) { continue; } UGLCovLst.Add(P); } else //Cell { if (nzBitCC <= 1) { continue; } if ((nzBit & P.UC.FreeB) == 0) { continue; } int B = nzBit & P.UC.FreeB; if (B == 0) { continue; } int rc = P.UC.rc; int kcc = 0, kccLim = (rnk == 0)? 2:1; foreach (var no in B.IEGet_BtoNo()) { if (!HB981._BQ[no].IsHit(rc)) { continue; } if (++kcc >= kccLim) { UGLCovLst.Add(P); break; } } } } #endregion if (UGLCovLst.Count < sz + rnk) { yield break; } Bit981 HC981 = new Bit981(); Bit981 HLapB = new Bit981(); Bit981 Can981 = new Bit981(); Combination cmbCvr = new Combination(UGLCovLst.Count, sz + rnk); int nxt = int.MaxValue; while (cmbCvr.Successor(nxt)) { ++GeneralLogicGen.ChkCov1; HC981.Clear(); Array.ForEach(cmbCvr.Index, m => HC981 |= UGLCovLst[m].rcbn2); if (!(HB981 - HC981).IsZero()) { goto LNextSet; //BaseSet is covered? } Bit981 CsubB = HC981 - HB981; if (CsubB.IsZero()) { goto LNextSet; //excludable candidates is exist? } List <UGLink> covUGLs = new List <UGLink>(); Array.ForEach(cmbCvr.Index, m => covUGLs.Add(UGLCovLst[m])); if (rnk == 0) { Can981 = CsubB; } else //if(rnk>0){ { bool SolFound = false; foreach (int n in CsubB.nzBit.IEGet_BtoNo()) { foreach (int rc in CsubB._BQ[n].IEGetRC()) { int kc = covUGLs.Count(Q => Q.IsHit(n, rc)); if (kc == rnk + 1) { Can981.BPSet(n, rc); SolFound = true; } } } if (!SolFound) { continue; } } ++GeneralLogicGen.ChkCov2; //***** UBC.addCoverSet(covUGLs, HC981, Can981, rnk); yield return(UBC); LNextSet: continue; } yield break; }