Exemplo n.º 1
0
        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;
                    }
                }
            }
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
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();
            }
        }
Exemplo n.º 4
0
        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);
        }