private void ScanRegion(RegionQueue regions, MutablePuzzle puzzle, Region region) { var placedDigits = region.GetPlacedDigits(); for (int i = 1; i <= Puzzle.LineLength; i++) { var digit = SudokuValues.FromHumanValue(i); if (placedDigits.HasAnyOptions(digit)) { continue; } var positions = region.GetPositions(digit); if (positions.IsSingle) { var index = positions.ToIndex(); var coords = region.GetCoordinate(index); var update = new CellUpdate(digit.Invert(), coords); puzzle.RemoveOptions(update); regions.Enqueue(RegionType.Row, coords.Row); regions.Enqueue(RegionType.Column, coords.Column); regions.Enqueue(RegionType.Box, coords.Box); } } }
private void ScanRegion(RegionQueue regions, MutablePuzzle puzzle, Region region) { var placedDigits = region.GetPlacedDigits(); for (int i = 0; i < Puzzle.LineLength; i++) { var cell = region[i]; if (!cell.IsSingle && cell.HasAnyOptions(placedDigits)) { var coords = region.GetCoordinate(i); puzzle.RemoveOptions(coords, placedDigits); var newCell = cell.RemoveOptions(placedDigits); if (newCell.IsSingle) { // since we have placed a digit we must // scan these regions again regions.Enqueue(RegionType.Row, coords.Row); regions.Enqueue(RegionType.Column, coords.Column); regions.Enqueue(RegionType.Box, coords.Box); } } } }
public void Apply(MutablePuzzle puzzle, RegionQueue changedRegions) { if (++depth > 10) { return; } while (changedRegions.TryDequeue(puzzle, out var region)) { for (int i = 0; i < Puzzle.LineLength; i++) { var value = region[i]; var coords = region.GetCoordinate(i); if (value.GetOptionCount() != 2) { continue; } // if there are are only 2 bits set, bitwise and // with the value - 1 will return the highest option var highestValue = new SudokuValues(value.Values & (value.Values - 1)); #if DEBUG Program.Debugger.AddAction($"Attempting {highestValue.Invert().Intersect(value)} in {coords}"); #endif var oldSolver = _solver; var changeset = new SingleCellChangeSet(new CellUpdate(highestValue, coords)); var newSolver = new Solver(changeset, _solver); _solver = newSolver; var(result, _) = newSolver.Solve(); _solver = oldSolver; #if DEBUG Program.Debugger.AddAction($"Result: {result}"); #endif switch (result) { case SolveResult.Success: puzzle.Absorb(newSolver.Puzzle); return; case SolveResult.Invalid: // we picked the wrong digit puzzle.RemoveOptions(new CellUpdate(highestValue.Invert(), coords)); return; } } } }
public void Apply(MutablePuzzle puzzle, RegionQueue changedRegions) { // keep scanning regions for naked singles, removing // options when digits are placed. when a digit is placed, // its box, row and column are added back to 'regions' so // they can be scanned again. while (changedRegions.TryDequeue(puzzle.Puzzle, out var region)) { ScanRegion(changedRegions, puzzle, region); } }
public void ApplyToRegionQueue(RegionQueue queue) { queue.Enqueue(RegionType.Row, _update.Coordinate.Row); queue.Enqueue(RegionType.Column, _update.Coordinate.Column); queue.Enqueue(RegionType.Box, _update.Coordinate.Box); }
public void ApplyToRegionQueue(RegionQueue queue) { }
public void ApplyToRegionQueue(RegionQueue queue) { queue.EnqueueAll(RegionQueue.GetFull()); }