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); } } } } } } }
protected override void OperateOn(SudokuModel model) { // We could look at all 2^N possible sets on all 3N of the model's regions, // but it is more efficient to only use the // possiblity set of each cell, and isolate that set on each intersecting region. for (var row = 0; row < model.Size; ++row) { for (var col = 0; col < model.Size; ++col) { if (!model.IsSolved(col, row)) { foreach (var region in model.GetIntersectingRegions(col, row)) { var checkedIter = GetCheckedIteration(region); if (checkedIter < model.GetLastChangedIterRegion(region.Type, region.I)) { _checkedIteration[region] = checkedIter; IsolateSet(model.GetPossibilitySetCell(col, row), region, model); } } } } } }