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 (SudokuValues row, SudokuValues col, SudokuValues box) GetValues(int rowVal, int colVal, int boxVal) { return( SudokuValues.FromHumanValue(rowVal), SudokuValues.FromHumanValue(colVal), SudokuValues.FromHumanValue(boxVal) ); }
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; } } } }
private static void PrintFieldPart(SudokuValues values, int part) { for (int v = part; v < part + 3; v++) Console.Write(values.Contains((byte)v) ? (v + 1).ToString(CultureInfo.InvariantCulture) : " "); }