public void Solve(Grid grid) { for (var colIdx = 0; colIdx < 9; ++colIdx) { var fixedDigits = new HashSet<int>(); for (var rowIdx = 0; rowIdx < 9; ++rowIdx) { if (grid.Squares[rowIdx, colIdx].IsSolved) { fixedDigits.Add(grid.Squares[rowIdx, colIdx].Digit); } } for (var digitToPlace = 1; digitToPlace <= 9; ++digitToPlace) { if (fixedDigits.Contains(digitToPlace)) continue; var possibleLocations = new List<int>(); for (var rowIdx = 0; rowIdx < 9; ++rowIdx) { if (grid.Squares[rowIdx, colIdx].IsSolved) continue; if (grid.Squares[rowIdx, colIdx].PossibleDigits.Contains(digitToPlace)) { possibleLocations.Add(rowIdx); } } if (possibleLocations.Count == 1) { grid.SetDigit(possibleLocations[0], colIdx, digitToPlace); } } } }
public void Solve(Grid grid) { for (var rowIdx = 0; rowIdx < 9; ++rowIdx) { for (var colIdx = 0; colIdx < 9; ++colIdx) { if (grid.Squares[rowIdx, colIdx].IsSolved) continue; if (grid.Squares[rowIdx, colIdx].PossibleDigits.Count != 1) continue; var digitToSet = grid.Squares[rowIdx, colIdx].PossibleDigits.First(); grid.SetDigit(rowIdx, colIdx, digitToSet); } } }
/// <summary> /// Given a partially solved grid, try each remaining possibility in turn and backtrack if necessary /// </summary> /// <param name="grid"></param> public void Solve(Grid grid) { var workingGrid = grid.Clone(); var unsolvedSquares = GetUnsolvedSquarePossibilities(grid); for (var remainingSquareIdx = 0; remainingSquareIdx < unsolvedSquares.Count; ++remainingSquareIdx) { var foundSquareSolution = false; var currentUnsolvedSquare = unsolvedSquares[remainingSquareIdx]; foreach (var possibleDigit in currentUnsolvedSquare.PossibleDigits) { if (possibleDigit > workingGrid.Squares[currentUnsolvedSquare.RowIdx, currentUnsolvedSquare.ColIdx].Digit) { var isValidToSet = workingGrid.EnsureValidToSetTheDigit(currentUnsolvedSquare.RowIdx, currentUnsolvedSquare.ColIdx, possibleDigit, false); if (isValidToSet) { workingGrid.Squares[currentUnsolvedSquare.RowIdx, currentUnsolvedSquare.ColIdx].SetDigit(possibleDigit); foundSquareSolution = true; } } if (foundSquareSolution) break; } // If have a working solution for the current unsolved square, move to the next if (foundSquareSolution) continue; // Otherwise roll back workingGrid.Squares[currentUnsolvedSquare.RowIdx, currentUnsolvedSquare.ColIdx].ClearDigit(); remainingSquareIdx = remainingSquareIdx - 2; // Move to the next possibility for the previous unsolved square (for loop moves forward one again) if (remainingSquareIdx < -1) break; } if (!workingGrid.IsSolved) return; // Copy the newly solved squares over for (var rowIdx = 0; rowIdx < 9; ++rowIdx) { for (var colIdx = 0; colIdx < 9; ++colIdx) { if (!grid.Squares[rowIdx, colIdx].IsSolved) { grid.SetDigit(rowIdx, colIdx, workingGrid.Squares[rowIdx, colIdx].Digit); } } } }
private void SolveForSquare(Grid grid, int firstRow, int lastRow, int firstCol, int lastCol) { var fixedDigits = new HashSet<int>(); for (var rowIdx = firstRow; rowIdx <= lastRow; ++rowIdx) { for (var colIdx = firstCol; colIdx <= lastCol; ++colIdx) { if (grid.Squares[rowIdx, colIdx].IsSolved) { fixedDigits.Add(grid.Squares[rowIdx, colIdx].Digit); } } } for (var digitToPlace = 1; digitToPlace <= 9; ++digitToPlace) { var possibleLocations = new List<Tuple<int, int>>(); if (fixedDigits.Contains(digitToPlace)) continue; for (var rowIdx = firstRow; rowIdx <= lastRow; ++rowIdx) { for (var colIdx = firstCol; colIdx <= lastCol; ++colIdx) { if (grid.Squares[rowIdx, colIdx].IsSolved) continue; if (grid.Squares[rowIdx, colIdx].PossibleDigits.Contains(digitToPlace)) { possibleLocations.Add(new Tuple<int, int>(rowIdx, colIdx)); } } } if (possibleLocations.Count == 1) { var location = possibleLocations[0]; grid.SetDigit(location.Item1, location.Item2, digitToPlace); } } }