public void Solve(Grid grid) { var boxCols = grid.GetBoxColumns(); var boxRows = grid.GetBoxRows(); for (var digit = 1; digit <= 9; ++digit) { for (var boxCol = 1; boxCol <= 3; ++boxCol) { var leftColumn = boxCols[boxCol].Item1; var middleColumn = boxCols[boxCol].Item1 + 1; var rightColumn = boxCols[boxCol].Item2; var possibleDigitBoxColumns = grid.FindThePotentialDigitInTheBoxColumns(boxRows, digit, leftColumn, middleColumn, rightColumn); if (possibleDigitBoxColumns.Values.All(v => v.Count != 1)) continue; // Where there is only one possible column for a digit within the box, remove it from that column for other boxes foreach (var possibleDigitBoxColumn in possibleDigitBoxColumns) { if (possibleDigitBoxColumn.Value.Count != 1) continue; var columnToClear = possibleDigitBoxColumn.Value[0]; for (var otherBoxRow = 1; otherBoxRow <= 3; ++otherBoxRow) { if (otherBoxRow == possibleDigitBoxColumn.Key) continue; for (var rowIdx = boxRows[otherBoxRow].Item1; rowIdx <= boxRows[otherBoxRow].Item2; ++rowIdx) { if (grid.Squares[rowIdx, columnToClear].IsSolved) continue; grid.Squares[rowIdx, columnToClear].RemovePossibleDigit(digit); } } } } } }
public void Solve(Grid grid) { const int IgnoreColumn = -1; var boxRows = grid.GetBoxRows(); var boxCols = grid.GetBoxColumns(); for (var digit = 1; digit <= 9; ++digit) { for (var boxCol = 1; boxCol <= 3; ++boxCol) { var leftColumn = boxCols[boxCol].Item1; var middleColumn = boxCols[boxCol].Item1 + 1; var rightColumn = boxCols[boxCol].Item2; var possibleDigitBoxColumns = grid.FindThePotentialDigitInTheBoxColumns(boxRows, digit, leftColumn, middleColumn, rightColumn); var countOfColumnBoxPairs = possibleDigitBoxColumns.Count(pb => pb.Value.Count == 2); if (countOfColumnBoxPairs < 2) continue; foreach (var possibleDigitBoxColumn in possibleDigitBoxColumns) { var firstBox = possibleDigitBoxColumn.Key; if (possibleDigitBoxColumn.Value.Count == 0) continue; if (possibleDigitBoxColumn.Value.Count > 2) continue; var firstColumn = possibleDigitBoxColumn.Value[0]; var secondColumn = possibleDigitBoxColumn.Value.Count > 1 ? possibleDigitBoxColumn.Value[1] : IgnoreColumn; foreach (var otherDigitBoxColumn in possibleDigitBoxColumns) { if (otherDigitBoxColumn.Key == possibleDigitBoxColumn.Key) continue; if (otherDigitBoxColumn.Value.Count > 2) continue; if (otherDigitBoxColumn.Value.Count == 0) continue; if (!otherDigitBoxColumn.Value.Contains(firstColumn)) continue; if (secondColumn != IgnoreColumn && !otherDigitBoxColumn.Value.Contains(secondColumn)) continue; var secondBox = otherDigitBoxColumn.Key; if (secondColumn == IgnoreColumn && otherDigitBoxColumn.Value.Count > 1) { secondColumn = otherDigitBoxColumn.Value[1]; } // Digit is restricted to two particular columns between two boxes // Therefore remove from the third var thirdBox = possibleDigitBoxColumns.Single(pb => pb.Key != firstBox && pb.Key != secondBox); for (var rowIdx = boxRows[thirdBox.Key].Item1; rowIdx <= boxRows[thirdBox.Key].Item2; ++ rowIdx) { grid.Squares[rowIdx, firstColumn].RemovePossibleDigit(digit); if (secondColumn != IgnoreColumn) { grid.Squares[rowIdx, secondColumn].RemovePossibleDigit(digit); } } } } } } }