public void SolveBoard() { ReducePossibleValues(Board); //int a=int.TryParse() var linearIndices = Enumerable.Range(0, 9) .SelectMany(i => Enumerable.Range(0, 9) .Select(j => new { Row = i, Col = j })); var list = linearIndices .Select(t => new { SudoCell = Board.SudoArray[t.Row, t.Col], RowIndex = t.Row, ColumnIndex = t.Col }) .Where(x => x.SudoCell.CellValue == 0 && x.SudoCell.PossibleValues != null) .Select(x => new { x.SudoCell, x.RowIndex, x.ColumnIndex, PVCount = x.SudoCell.PossibleValues.Count }) .OrderBy(x => x.PVCount) .ToList(); // this looks like a bad logic (iterating over every single possible value and running the algorithm) // but in reality the board will be solved much earlier ... needs more testing though foreach (var a in list) { foreach (var pv in a.SudoCell.PossibleValues) { var newBoard = Board.CreateCopy(); newBoard.SolveCell(pv, a.RowIndex, a.ColumnIndex); bool isSolved = SudokuHelper.IsBoardSolved(newBoard); if (isSolved) { //IsSolved = true; Board = newBoard; return; } } } }
public Sudoku(string field) { if (string.IsNullOrWhiteSpace(field)) { throw new ArgumentException("The field can't be null or whitespace."); } _field = SudokuHelper.FieldFromString(field); _side = _field.GetLength(0); }
public string Solve() { HashSet <byte>[] rowDigits = new HashSet <byte> [_side]; HashSet <byte>[] columnDigits = new HashSet <byte> [_side]; HashSet <byte>[] quadrantDigits = new HashSet <byte> [_side]; for (int i = 0; i < _side; i++) { rowDigits[i] = new HashSet <byte>(); columnDigits[i] = new HashSet <byte>(); quadrantDigits[i] = new HashSet <byte>(); } int index = 0; int givenDigits = 0; for (int i = 0; i < _side; i++) { for (int j = 0; j < _side; j++) { if (_field[i, j] > 0) { if (AddDigit(index, _field[i, j], rowDigits, columnDigits, quadrantDigits)) { givenDigits++; } else { throw new DuplicateGivenException($"Duplicate entry '{_field[i, j]}' at index {index + 1} (row: {i + 1}, col: {j + 1})."); } } index++; } } if (givenDigits == 0 || (_side == 9 && givenDigits < 17)) // 9x9 Sudokus need to have at least 17 givens { throw new InsufficientGivensException(); } if (Solve(0, rowDigits, columnDigits, quadrantDigits)) { return(SudokuHelper.FieldToString(_field)); } else { throw new UnsolvableSudokuException(); } }
static void Main(string[] args) { List <List <int> > grid = new List <List <int> >(); grid.Add(new List <int> { 0, 8, 1, 0, 4, 0, 0, 0, 0 }); grid.Add(new List <int> { 0, 5, 6, 9, 0, 7, 4, 0, 0 }); grid.Add(new List <int> { 0, 0, 0, 0, 1, 5, 0, 9, 0 }); grid.Add(new List <int> { 0, 0, 0, 0, 0, 3, 8, 5, 7 }); grid.Add(new List <int> { 8, 4, 0, 0, 6, 0, 0, 2, 3 }); grid.Add(new List <int> { 7, 3, 9, 2, 0, 0, 0, 0, 0 }); grid.Add(new List <int> { 0, 0, 8, 3, 0, 6, 5, 7, 0 }); grid.Add(new List <int> { 0, 6, 0, 5, 8, 0, 0, 0, 0 }); grid.Add(new List <int> { 0, 0, 0, 0, 7, 0, 3, 6, 0 }); SudokuHelper helper = new SudokuHelper(); helper.PrintGrid(grid); helper.Solve(grid); }
static bool InputSudoku(out Definition.Sudoku sudoku) { sudoku = null; Console.WriteLine("input sudoku data:"); Console.WriteLine(); Console.WriteLine("(whitespace to separate elements"); Console.WriteLine(" _ to indicate empty element"); Console.WriteLine(" new line to separete rows"); Console.WriteLine(" esc to cancel)"); Console.WriteLine(); bool cancelled = false; int size = SudokuHelper.SUDOKU_SPLIT_LEN; int[] values = new int[size * size]; for (int i = 0; i < size;) { Console.WriteLine("line " + (i + 1)); StringBuilder lineBuilder = new StringBuilder(); bool endOfLine = false; while (!endOfLine && !cancelled) { var key = Console.ReadKey(); switch (key.Key) { case ConsoleKey.Enter: endOfLine = true; break; case ConsoleKey.Escape: cancelled = true; break; case ConsoleKey.Backspace: if (lineBuilder.Length > 0) { lineBuilder.Remove(lineBuilder.Length - 1, 1); } break; } switch (key.KeyChar) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '_': case ' ': lineBuilder.Append(key.KeyChar); break; default: break; } } if (cancelled) { Console.WriteLine("cancelled"); return(false); } int[] lineValues; if (!SudokuHelper.TryParse(lineBuilder.ToString(), out lineValues)) { Console.WriteLine("wrong line data"); i--; continue; } Array.Copy(lineValues, 0, values, i++ *size, size); Console.WriteLine(); } sudoku = new Definition.Sudoku(); using (var sudokuElementIterator = new SudokuElementEnumerable(sudoku, SudokuElementTravelType.Row).GetEnumerator()) using (var valueIterator = values.AsEnumerable().GetEnumerator()) { while (sudokuElementIterator.MoveNext() && valueIterator.MoveNext()) { var element = sudokuElementIterator.Current; int value = valueIterator.Current; if (value > 0) { element.SetValue(value); } } } if (!sudoku.Validate()) { sudoku = null; Console.WriteLine("invalid sudoku data"); return(false); } return(true); }