private void Prepare() { if (pAnMan.GStage != GStageMemo) { GStageMemo = pAnMan.GStage; ALSMan.Initialize(); ALSMan.PrepareALSLinkMan(1); } }
public bool ALS_DeathBlossomExt() { Prepare(); if (ALSMan.ALSLst == null || ALSMan.ALSLst.Count <= 2) { return(false); } ALSMan.QSearch_Cell2ALS_Link(); for (int sz = 2; sz <= 4; sz++) //Size 5 and over ALS DeathBlossom was not found? { if (_ALS_DeathBlossomSubEx(sz, stmLinked:true)) { return(true); } } return(false); }
//ALS Chain is an algorithm that connects ALS into a loop in RCC. // http://csdenpe.web.fc2.com/page52.html public bool ALS_Chain() { Prepare(); if (ALSMan.ALSLst == null || ALSMan.ALSLst.Count <= 3) { return(false); } ALSMan.QSearch_ALS2ALS_Link(true); //T:doubly+singly (F:only singly) for (int szCtrl = 3; szCtrl <= 12; szCtrl++) //Search from small size ALS-Chain { if (pAnMan.CheckTimeOut()) { return(false); } var SolStack = new Stack <UALSPair>(); foreach (var ALSHead in ALSMan.ALSLst.Where(p => p.ConnLst != null && !p.LimitF)) { if (!ALSHead.singly) { continue; } bool limitF = false; foreach (var LK0 in ALSHead.ConnLst) { SolStack.Push(LK0); LK0.rcUsed = LK0.ALSpre.B81 | LK0.ALSnxt.B81; int szCtrlX = szCtrl - LK0.ALSpre.Size - LK0.ALSnxt.Size; _Search_ALSChain(LK0, LK0, SolStack, szCtrlX, ref limitF); //First Recursive Search if (SolCode > 0) { return(true); } SolStack.Pop(); } if (!limitF) { ALSHead.LimitF = true; } //When the solution is within the size limit, do not search by the next size } } return(false); }
private bool _ALSXZsub(int sz) { if (ALSMan.ALSLst.Count < 2) { return(false); } var cmb = new Combination(ALSMan.ALSLst.Count, 2); int nxt = 99; while (cmb.Successor(nxt)) //Select two ALSs { UALS UA = ALSMan.ALSLst[cmb.Index[0]]; nxt = 0; if (!UA.singly || UA.Size == 1 || UA.Size > (sz - 2)) { continue; } UALS UB = ALSMan.ALSLst[cmb.Index[1]]; nxt = 1; if (!UB.singly || UB.Size == 1 || (UA.Size + UB.Size) != sz) { continue; } int RCC = ALSMan.Get_AlsAlsRcc(UA, UB); //Common numbers, House contact, Without overlap if (RCC == 0) { continue; } if (RCC.BitCount() == 1) //===== Singly Linked ===== { int EnoB = (UA.FreeB & UB.FreeB).DifSet(RCC); //Exclude candidate digit if (EnoB > 0 && _ALSXZ_SinglyLinked(UA, UB, RCC, EnoB)) { SolCode = 2; ALSXZ_SolResult(RCC, UA, UB); if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } } else if (RCC.BitCount() == 2) //===== Doubly Linked ===== { if (_ALSXZ_DoublyLinked(UA, UB, RCC)) { SolCode = 2; ALSXZ_SolResult(RCC, UA, UB); if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } } } return(false); }
private bool _XYZwingALSSub(int wsz) //simple UVWXYZwing { List <UCell> FBCX = pBDL.FindAll(p => p.FreeBC == wsz); if (FBCX.Count == 0) { return(false); } foreach (var P0 in FBCX) //Forcused Cell { int b0 = P0.b; //Forcused Block for (int no = 0; no < 9; no++) { int noB = 1 << no; Bit81 P0con = (new Bit81(pBDL, noB)) & ConnectedCells[P0.rc]; Bit81 Pin = P0con & HouseCells[18 + b0]; for (int dir = 0; dir < 2; dir++) //dir 0:row 1:col { int rcDir = (dir == 0)? P0.r: (9 + P0.c); Bit81 Pin2 = Pin - HouseCells[rcDir]; //ALS candidate position in the block if (Pin2.IsZero()) { continue; } Bit81 Pout = (P0con & HouseCells[rcDir]) - HouseCells[18 + P0.b]; //ALS candidate position outside the block foreach (var ALSout in ALSMan.IEGetCellInHouse(1, noB, Pout, rcDir)) //ALS out of Forcused Block { int FreeBOut2 = ALSout.FreeB.DifSet(noB); Bit81 EOut = new Bit81(); //#no existence position(outer-ALS) foreach (var P in ALSout.UCellLst.Where(p => (p.FreeB & noB) > 0)) { EOut.BPSet(P.rc); } foreach (var ALSin in ALSMan.IEGetCellInHouse(1, noB, Pin2, 18 + b0)) { int FreeBin2 = ALSin.FreeB.DifSet(noB); Bit81 Ein = new Bit81(); //#no existence position(inner-ALS) foreach (var P in ALSin.UCellLst.Where(p => (p.FreeB & noB) > 0)) { Ein.BPSet(P.rc); } int Cover = P0.FreeB.DifSet(ALSout.FreeB | ALSin.FreeB); if (Cover != 0) { continue; //Numbers in inner-ALS and outer-ALS cover numbers in the Forcused cell } Bit81 Epat = EOut | Ein; //Cells covered by excluded Cells&Digit if (Epat.IsZero()) { continue; } bool SolFound = false; string msg3 = ""; int FreeBin3 = P0.FreeB.DifSet(FreeBOut2 | FreeBin2); foreach (var E in pBDL.Where(p => (p.FreeB & noB) > 0)) { if (E.rc == P0.rc || Pout.IsHit(E.rc) || Pin2.IsHit(E.rc)) { continue; } if (!(Epat - ConnectedCells[E.rc]).IsZero()) { continue; } if (FreeBin3 > 0 && !ConnectedCells[E.rc].IsHit(P0.rc)) { continue; } E.CancelB = noB; SolFound = true; msg3 += " " + E.rc.ToRCString(); } if (SolFound) { SolCode = 2; string[] xyzWingName = { "XYZ-Wing", "WXYZ-Wing", "VWXYZ-Wing", "UVWXYZ-Wing" }; string SolMsg = xyzWingName[wsz - 3] + "(ALS)"; if (SolInfoB) { P0.SetNoBBgColor(P0.FreeB, AttCr, SolBkCr2); foreach (var P in ALSin.UCellLst) { P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr); } foreach (var P in ALSout.UCellLst) { P.SetNoBBgColor(P.FreeB, AttCr, SolBkCr); } string msg0 = " Pivot: " + P0.rc.ToRCString(); string st = ""; foreach (var P in ALSin.UCellLst) { st += " " + P.rc.ToRCString(); } string msg1 = " in: " + st.ToString_SameHouseComp(); st = ""; foreach (var P in ALSout.UCellLst) { st += " " + P.rc.ToRCString(); } string msg2 = " out: " + st.ToString_SameHouseComp(); st = ""; foreach (var rc in Pin2.IEGet_rc()) { st += " " + rc.ToRCString(); } Result = SolMsg + msg0 + msg1 + msg2; ResultLong = SolMsg + "\r" + msg0 + "\r " + msg1 + "\r " + msg2 + "\r Eliminated: " + msg3.ToString_SameHouseComp(); } if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } foreach (var E in pBDL.Where(p => (p.FreeB & noB) > 0)) { E.CancelB = 0; } SolFound = false; } } } } } } return(false); }
private bool _ALSXYWingSub(int szT) { //(ALS sorted by size) foreach (var UC in ALSMan.ALSLst.Where(p => p.Size <= szT - 2)) { if (!UC.singly) { continue; } int szS = szT - UC.Size; UALS UA, UB, UApre = null; int nxt = 0, RccAC = -1, RccBC = -1; var cmb = new Combination(ALSMan.ALSLst.Count, 2); while (cmb.Successor(nxt)) { nxt = 0; UA = ALSMan.ALSLst[cmb.Index[0]]; if (!UA.singly || UA == UC || UA.Size > szS - 1) { continue; } if (UA != UApre) { RccAC = ALSMan.Get_AlsAlsRcc(UA, UC); //RCC if (RccAC.BitCount() != 1) { continue; } UApre = UA; } UB = ALSMan.ALSLst[cmb.Index[1]]; if (!UB.singly || UB.Size > (szS - UA.Size)) { continue; //Skip using "Sort by size" } nxt = 1; if (UB == UC || UB.Size != (szS - UA.Size)) { continue; } if (!(UA.B81 & UB.B81).IsZero()) { continue; //Overlap } RccBC = ALSMan.Get_AlsAlsRcc(UB, UC); //RCC if (RccBC.BitCount() != 1) { continue; } if (RccAC == RccBC) { continue; } int EFrB = (UA.FreeB & UB.FreeB).DifSet(RccAC | RccBC); if (EFrB == 0) { continue; } foreach (var no in EFrB.IEGet_BtoNo()) { int noB = (1 << no); Bit81 UE = new Bit81(); foreach (var P in UA.UCellLst.Where(p => (p.FreeB & noB) > 0)) { UE.BPSet(P.rc); } foreach (var P in UB.UCellLst.Where(p => (p.FreeB & noB) > 0)) { UE.BPSet(P.rc); } Bit81 TBD = (new Bit81(pBDL, noB)) - (UA.B81 | UB.B81 | UC.B81); foreach (var rc in TBD.IEGet_rc()) { if (!(UE - ConnectedCells[rc]).IsZero()) { continue; } pBDL[rc].CancelB = noB; SolCode = 2; } if (SolCode > 0) //===== ALS XY-Wing found ===== { ALSXYWing_SolResult(UA, UB, UC, RccAC, RccBC); if (__SimpleAnalizerB__) { return(true); } if (!pAnMan.SnapSaveGP(true)) { return(true); } } } } } return(false); }