Example #1
0
        public static SudokuPuzzle Parse(string puzzleAsString)
        {
            const char placeHolderChar = '.';

            var puzzle = new SudokuPuzzle();

            char[] allowedCharacters   = { placeHolderChar, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
            var    allCharacters       = puzzleAsString.ToCharArray();
            var    onlyValidCharacters = allCharacters.Where(c => allowedCharacters.Contains(c)).ToArray();

            int rowIndex    = 0;
            int columnIndex = 0;

            for (int i = 0; i < onlyValidCharacters.Length; i++)
            {
                var character = onlyValidCharacters[i];
                if (allowedCharacters.Contains(character))
                {
                    if (character != placeHolderChar)
                    {
                        byte value = (byte)(character - 48);
                        puzzle.SetValue(rowIndex + 1, columnIndex + 1, value);
                    }

                    columnIndex = (columnIndex + 1) % 9;
                    if (columnIndex == 0)
                    {
                        rowIndex += 1;
                    }
                }
            }

            return(puzzle);
        }
Example #2
0
        private static ValidationResult ValidateEachNumberOnlyOnceInASection(SudokuPuzzle puzzle)
        {
            for (int sectionIndex = 0; sectionIndex < 9; sectionIndex++)
            {
                var numbersInSection = new List <byte>();

                for (int number = 1; number <= 9; number++)
                {
                    int rowNr    = number % 3 == 0 ? 3 : number % 3;
                    int columnNr = (int)Math.Ceiling(number / 3d);

                    int absoluteRowNr    = rowNr + ((sectionIndex % 3) * 3);
                    int absoluteColumnNr = columnNr + ((sectionIndex % 3) * 3);

                    var positionValue = puzzle[absoluteRowNr, absoluteColumnNr];

                    if (!positionValue.HasValue)
                    {
                        return(ValidationResult.CreateInvalid(
                                   $"Value missing at position: row={absoluteRowNr}, column={absoluteColumnNr}",
                                   absoluteRowNr,
                                   absoluteColumnNr));
                    }

                    var numberValue = positionValue.Value;
                    numbersInSection.Add(numberValue);
                }

                var distinct = numbersInSection.Distinct().ToArray();
                if (!distinct.SequenceEqual(numbersInSection))
                {
                    var differentIndexes = distinct.Select((item, index) => new { item, index })
                                           .Where(x => x.item != numbersInSection[x.index])
                                           .Select(x => x.index)
                                           .ToArray();

                    var number = differentIndexes.Any() ? differentIndexes.First() + 1 : 9;

                    int rowNr    = number % 3 == 0 ? 3 : number % 3;
                    int columnNr = (int)Math.Ceiling(number / 3d);

                    int absoluteRowNr    = rowNr + ((sectionIndex % 3) * 3);
                    int absoluteColumnNr = columnNr + ((sectionIndex % 3) * 3);

                    return(ValidationResult.CreateInvalid(
                               $"Section {sectionIndex + 1} is invalid",
                               absoluteRowNr,
                               absoluteColumnNr));
                }
            }

            return(ValidationResult.CreateValid());
        }
Example #3
0
        internal static ValidationResult Validate(SudokuPuzzle puzzle)
        {
            var result = ValidateEachNumberOnlyOnceInARow(puzzle);

            if (!result.Valid)
            {
                return(result);
            }

            result = ValidateEachNumberOnlyOnceInAColumn(puzzle);

            if (!result.Valid)
            {
                return(result);
            }

            return(ValidateEachNumberOnlyOnceInASection(puzzle));
        }
Example #4
0
        private static ValidationResult ValidateEachNumberOnlyOnceInARow(SudokuPuzzle puzzle)
        {
            for (int rowNr = 1; rowNr <= 9; rowNr++)
            {
                var numbersInRow = new List <byte>();

                for (int columnNr = 1; columnNr <= 9; columnNr++)
                {
                    var positionValue = puzzle[rowNr, columnNr];

                    if (!positionValue.HasValue)
                    {
                        return(ValidationResult.CreateInvalid(
                                   $"Value missing at position: row={rowNr}, column={columnNr}",
                                   rowNr,
                                   columnNr));
                    }

                    var number = positionValue.Value;
                    numbersInRow.Add(number);
                }

                var distinct = numbersInRow.Distinct().ToArray();
                if (!distinct.SequenceEqual(numbersInRow))
                {
                    var differentIndexes = distinct.Select((item, index) => new { item, index })
                                           .Where(x => x.item != numbersInRow[x.index])
                                           .Select(x => x.index)
                                           .ToArray();
                    var differentColumnNr = differentIndexes.Any() ? differentIndexes.First() + 1 : 9;

                    return(ValidationResult.CreateInvalid(
                               $"Row {rowNr} is invalid",
                               rowNr, differentColumnNr));
                }
            }

            return(ValidationResult.CreateValid());
        }
Example #5
0
 public SudokuPuzzle Solve(SudokuPuzzle puzzle)
 {
     return(new SudokuPuzzle());
 }
Example #6
0
 public ValidationResult Validate(SudokuPuzzle puzzle)
 {
     return(PuzzleValidator.Validate(puzzle));
 }