static SudokuCandidate[] Filter(SudokuSolver ss, int cage, Func <int, bool> included) { int Cells = ss.Cells; List <SudokuCandidate> toRemove = new List <SudokuCandidate>(); for (int i = 0; i < Cells; ++i) { if (!included(i + 1)) { CageOptional co = ss.GetCageOptional(cage, i); if (co.Included) { foreach (SudokuCandidate sc in co.UnselectedCandidates) { if (!sc.IsMarked) { toRemove.Add(sc); sc.MarkCandidate(true); } } } } } SudokuCandidate[] removed = toRemove.ToArray(); for (int i = 0; i < removed.Length; ++i) { SudokuCandidate sc = removed[i]; ss.DiscardCandidate(sc); sc.MarkCandidate(false); } return(removed.ToArray()); }
protected void CreateOptionals(SudokuGrid grid, int nc) { co = new CageOptional[nc, Cells]; for (int i0 = 0; i0 < nc; ++i0) { for (int i1 = 0; i1 < Cells; ++i1) { co[i0, i1] = new CageOptional(grid.cageInfo); } } }
public void AddCageOptional(CageOptional c) { this.cageOptional = c; AddCandidate(c); }
/* * public SudokuSolver(string[] lines) * { * CreateMatrix(); * Apply(lines); * } */ void CreateMatrix(SudokuGrid grid) { // Create requirements - columns of 0/1 matrix int num_cages = grid.NumCages; int diags = 0; if (grid.MajorDiagonal) { ++diags; } if (grid.MinorDiagonal) { ++diags; } int d = grid.MajorDiagonal ? 1 : 0; // Where minor diagonal is found CreateRequirements(grid, Cells * Cells * 4 + diags * Cells); CreateOptionals(grid, num_cages); Houses[] houses = new Houses[] { Houses.Cell, Houses.Column, Houses.Row, Houses.Box }; for (int i0 = 0; i0 < Cells; ++i0) { for (int i1 = 0; i1 < Cells; ++i1) { for (int type = 0; type < 4; ++type) { Houses house = houses[type]; SudokuRequirement c = GetRequirement(i0, i1, house); c.i0 = i0; c.i1 = i1; c.house = house; requirements.AddRequirement(c); } } } if (grid.MajorDiagonal) { for (int i0 = 0; i0 < Cells; ++i0) { SudokuRequirement c = GetDiagonalRequirement(0, i0); c.i0 = i0; c.i1 = -1; c.house = Houses.MajorDiagonal; requirements.AddRequirement(c); } } if (grid.MinorDiagonal) { for (int i0 = 0; i0 < Cells; ++i0) { SudokuRequirement c = GetDiagonalRequirement(d, i0); c.i0 = i0; c.i1 = -1; c.house = Houses.MinorDiagonal; requirements.AddRequirement(c); } } for (int i0 = 0; i0 < num_cages; ++i0) { for (int i1 = 0; i1 < Cells; ++i1) { CageOptional ca = GetCageOptional(i0, i1); ca.i0 = i0; ca.i1 = i1; ca.house = Houses.Cage; //optionals.AddRequirement(ca); ca.SetIncluded(); } } // Create candidates - rows of 0/1 matrix CreateCandidates(new SudokuCandidate[Cells * Cells * Cells]); CreateSolution(Cells * Cells); for (int x = 0; x < Cells; ++x) { for (int y = 0; y < Cells; ++y) { int cage = grid.CageAt(x, y); int box = grid.BoxAt(x, y); for (int n = 0; n < Cells; ++n) { SudokuCandidate k = new SudokuCandidate(x, y, n, box, cage); k.AddCandidate(GetRequirement(x, y, Houses.Cell)); k.AddCandidate(GetRequirement(x, n, Houses.Column)); k.AddCandidate(GetRequirement(y, n, Houses.Row)); k.AddCandidate(GetRequirement(box, n, Houses.Box)); if (grid.MajorDiagonal && x == y) { k.AddCandidate(GetDiagonalRequirement(0, n)); } if (grid.MinorDiagonal && x == Cells - y - 1) { k.AddCandidate(GetDiagonalRequirement(d, n)); } if (cage != -1) { k.AddCageOptional(GetCageOptional(cage, n)); } tr[trc++] = k; // Discard candidates where cage size already reached 1 //if (cage != -1 && grid.cageInfo.sizes[cage] == 1 && n + 1 != grid.cageInfo.totals[cage]) // DiscardCandidate(k); } } } // Discard candidates that do not meet cage total for (int i0 = 0; i0 < num_cages; ++i0) { CageOptional.CheckRemains(this, grid.cageInfo, i0, -1); } /* * if (grid.IsKiller) * { * SudokuGrid.CageInfo info = grid.cageInfo; * for (int ca = 0; ca < info.cages.Length; ++ca) * { * List<Point> pts = new List<Point>(); * for (int x = 0; x < Cells; ++x) * for (int y = 0; y < Cells-1; ++y) * if (info.cages[x, y] == ca) * pts.Add(new Point(x, y)); * int[] ns = new int[Cells]; * for (int i = 0; i < Cells; ++i) ns[i] = i; * Candidate k = new Candidate(); * KillerRequire(k, info.totals[ca], pts.ToArray(), ns); * } * } */ }