protected override void OperateOn(SudokuModel model) { for (var iType = 0; iType < 3; ++iType) { var type = (RegionType)iType; for (var i = 0; i < model.Size; ++i) { var region = new Region(type, i); var tuple = new Tuple<SudokuModel, Region>(model, region); if (GetCheckedIteration(tuple) < model.GetLastChangedIterRegion(type, i)) { _checkedIteration[tuple] = model.ChangeCount; foreach (var unsolved in model.GetUnsolvedValues(type, i)) { var timesFound = 0; Cell? foundAt = null; foreach (var cell in model.GetCells(type, i)) { if ((model.GetPossibilitySetCell(cell.Column, cell.Row) & (1 << unsolved)) != 0) { ++timesFound; foundAt = cell; if (timesFound > 1) { break; } } } if (timesFound == 1) { if (foundAt != null) { model.SetValueOptimized(foundAt.Value.Column, foundAt.Value.Row, unsolved, type, i); } } } } } } }
int GetCheckedIteration(Region region) { if (!_checkedIteration.ContainsKey(region)) { _checkedIteration[region] = -1; } return _checkedIteration[region]; }
static void IsolateSet(int set, Region region, SudokuModel model) { var cells = model.GetCells(region.Type, region.I); var cellsNotContainedBySet = cells.Where(cell => (model.GetPossibilitySetCell(cell.Column, cell.Row) | set) != set).ToList(); var numCellsContainedBySet = cells.Length - cellsNotContainedBySet.Count; if (numCellsContainedBySet != set.HiBitCount()) { return; } // we now know that each of the numbers in the set must be exclusively in // one of the contained cells, so we eliminate that set from all other cells' // possibility bits. var mask = ~set; foreach (var cell in cellsNotContainedBySet) { var poss = model.GetPossibilitySetCell(cell.Column, cell.Row); model.SetPossibilitySetCell(cell.Column, cell.Row, poss & mask); } }
/// <summary> /// Returns the Row, Column, and Square that contain that cell. /// </summary> public IEnumerable<Region> GetIntersectingRegions(int col, int row) { if (_intersectingRegions[col, row] == null) { _intersectingRegions[col, row] = new Region[3]; _intersectingRegions[col, row][0] = new Region(RegionType.Column, col); _intersectingRegions[col, row][1] = new Region(RegionType.Row, row); int sqI = (row / _sizeSqrt) * _sizeSqrt + col / _sizeSqrt; _intersectingRegions[col, row][2] = new Region(RegionType.Square, sqI); } return _intersectingRegions[col, row]; }