Пример #1
0
        /// <summary>
        /// Output the solutions to the given <see cref="SudokuPuzzle"/> to the given file path
        /// </summary>
        /// <param name="filepath">The file to which the solutions will be written</param>
        /// <param name="filer">Used to convert <see cref="SudokuPuzzle"/>s into lists of strings</param>
        /// <param name="puzzleToSolve">The <see cref="SudokuPuzzle"/> being solved</param>
        /// <param name="solutions">A list of the solutions to the <see cref="SudokuPuzzle"/> being solved</param>
        private static void OutputSolutions(string filepath, SudokuFiler filer, SudokuPuzzle puzzleToSolve, List <SudokuPuzzle> solutions)
        {
            if (solutions.Count == 0)
            {
                List <string> unsolvablePuzzle = filer.ConvertToStrings(puzzleToSolve);
                unsolvablePuzzle.Add(string.Empty);
                unsolvablePuzzle.Add("Unsolvable Puzzle");
                WriteToFile(filepath, unsolvablePuzzle);
            }
            else if (solutions.Count == 1)
            {
                List <string> puzzleOutput = filer.ConvertToStrings(puzzleToSolve);
                List <string> solution     = filer.ConvertToStrings(solutions[0]);
                puzzleOutput.Add(string.Empty);
                puzzleOutput.Add("Solved");
                puzzleOutput.AddRange(solution);
                WriteToFile(filepath, puzzleOutput);
            }
            else
            {
                List <string> puzzleOutput = filer.ConvertToStrings(puzzleToSolve);
                puzzleOutput.Add(string.Empty);
                puzzleOutput.Add("Multiple Solutions");

                foreach (SudokuPuzzle solution in solutions)
                {
                    puzzleOutput.Add(string.Empty);
                    puzzleOutput.AddRange(filer.ConvertToStrings(solution));
                }

                WriteToFile(filepath, puzzleOutput);
            }
        }
Пример #2
0
 private static void WritePuzzle(string filePath, SudokuPuzzle sp, bool writeHtml = true)
 {
     using (StreamWriter sr = new StreamWriter(filePath))
     {
         sr.Write((writeHtml)?sp.ToHTMLString():sp.ToString());
     }
 }
Пример #3
0
        public static SudokuPuzzle MakeSolvedPuzzle()
        {
            // known solution from: http://www.sudokukingdom.com/images/rules_solved.jpg
            var rows = new SudokuValue[][] {
                new SudokuValue [] { SudokuValue.TWO, SudokuValue.FOUR, SudokuValue.EIGHT, SudokuValue.THREE, SudokuValue.NINE, SudokuValue.FIVE, SudokuValue.SEVEN, SudokuValue.ONE, SudokuValue.SIX },
                new SudokuValue [] { SudokuValue.FIVE, SudokuValue.SEVEN, SudokuValue.ONE, SudokuValue.SIX, SudokuValue.TWO, SudokuValue.EIGHT, SudokuValue.THREE, SudokuValue.FOUR, SudokuValue.NINE },
                new SudokuValue [] { SudokuValue.NINE, SudokuValue.THREE, SudokuValue.SIX, SudokuValue.SEVEN, SudokuValue.FOUR, SudokuValue.ONE, SudokuValue.FIVE, SudokuValue.EIGHT, SudokuValue.TWO },

                new SudokuValue [] { SudokuValue.SIX, SudokuValue.EIGHT, SudokuValue.TWO, SudokuValue.FIVE, SudokuValue.THREE, SudokuValue.NINE, SudokuValue.ONE, SudokuValue.SEVEN, SudokuValue.FOUR },
                new SudokuValue [] { SudokuValue.THREE, SudokuValue.FIVE, SudokuValue.NINE, SudokuValue.ONE, SudokuValue.SEVEN, SudokuValue.FOUR, SudokuValue.SIX, SudokuValue.TWO, SudokuValue.EIGHT },
                new SudokuValue [] { SudokuValue.SEVEN, SudokuValue.ONE, SudokuValue.FOUR, SudokuValue.EIGHT, SudokuValue.SIX, SudokuValue.TWO, SudokuValue.NINE, SudokuValue.FIVE, SudokuValue.THREE },

                new SudokuValue [] { SudokuValue.EIGHT, SudokuValue.SIX, SudokuValue.THREE, SudokuValue.FOUR, SudokuValue.ONE, SudokuValue.SEVEN, SudokuValue.TWO, SudokuValue.NINE, SudokuValue.FIVE },
                new SudokuValue [] { SudokuValue.ONE, SudokuValue.NINE, SudokuValue.FIVE, SudokuValue.TWO, SudokuValue.EIGHT, SudokuValue.SIX, SudokuValue.FOUR, SudokuValue.THREE, SudokuValue.SEVEN },
                new SudokuValue [] { SudokuValue.FOUR, SudokuValue.TWO, SudokuValue.SEVEN, SudokuValue.NINE, SudokuValue.FIVE, SudokuValue.THREE, SudokuValue.EIGHT, SudokuValue.SIX, SudokuValue.ONE }
            };

            var puzzle = new SudokuPuzzle();
            for (int i = 0; i < rows.Length; i++)
            {
                for (int j = 0; j < rows.Length; j++)
                {
                    puzzle.SetValue(i, j, rows[i][j]);
                }
            }

            return puzzle;
        }
Пример #4
0
        public static SudokuPuzzleResultModel Search(SudokuPuzzle puzzle)
        {
            Steps.Clear();

            _stopwatch = new Stopwatch();
            _stopwatch.Start();

            if (puzzle.IsValidPuzzle() == false)
            {
                _stopwatch.Stop();

                return(new SudokuPuzzleResultModel
                {
                    ExecutionTime = _stopwatch.ElapsedMilliseconds,
                    IsValidPuzzle = false
                });
            }

            var result = Backtracking(puzzle);

            _stopwatch.Stop();

            return(new SudokuPuzzleResultModel
            {
                ExecutionTime = _stopwatch.ElapsedMilliseconds,
                Solution = result?.ToEnumerableValues().ToArray(),
                Steps = Steps.ToArray(),
                IsValidPuzzle = true,
                SolutionFound = result != null
            });
        }
Пример #5
0
        public void SudokuPuzzle_CanSetValueForCell()
        {
            var puzzle = new SudokuPuzzle();
            puzzle.SetValue(0, 3, SudokuValue.NINE);

            Assert.AreEqual(SudokuValue.NINE, puzzle.GetValue(0, 3));
        }
Пример #6
0
        /// <summary>
        /// The main entry point of the program
        /// </summary>
        /// <param name="args">An array of command line arguments</param>
        public static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("Error: Missing file paths");
            }
            else if (!File.Exists(args[0]))
            {
                Console.WriteLine($"Error: Could not find file {args[0]}");
            }
            else
            {
                try
                {
                    SudokuFiler  filer                  = new SudokuFiler(args[0]);
                    SudokuPuzzle puzzleToSolve          = filer.CreatePuzzle();
                    SudokuSolver.SudokuSolver solver    = new SudokuSolver.SudokuSolver();
                    List <SudokuPuzzle>       solutions = solver.Solve(puzzleToSolve);
                    OutputSolutions(args[1], filer, puzzleToSolve, solutions);
                }
                catch (Exception)
                {
                    string[]      sudokuFile = File.ReadAllLines(args[0]);
                    List <string> lines      = new List <string>();
                    foreach (string line in sudokuFile)
                    {
                        lines.Add(line);
                    }

                    lines.Add(string.Empty);
                    lines.Add("Bad Puzzle");
                    WriteToFile(args[1], lines);
                }
            }
        }
Пример #7
0
 private void EnterSolution(Stack <Node> solution, SudokuPuzzle puzzle)
 {
     while (solution.Count > 0)
     {
         List <ColumnHeader> rowHeaders = solution.Pop().GetLinkedHeaders();
         InterpretRow(rowHeaders, puzzle.PuzzleMatrix);
     }
 }
Пример #8
0
        public void SolveSudoku(SudokuPuzzle puzzle)
        {
            ReadInClues(puzzle);
            Stack <Node> solution = Search();

            EnterSolution(solution, puzzle);
            RemoveClues();
        }
Пример #9
0
        public SudokuSolver(SudokuPuzzle puzzle)
        {
            if (puzzle == null)
            {
                throw new ArgumentNullException("puzzle");
            }

            this.Puzzle = puzzle.Clone() as SudokuPuzzle;
        }
Пример #10
0
        public void SudokuSolver_ClonesArgumentToAvoidModifyingOriginal()
        {
            var puzzle = new SudokuPuzzle();
            puzzle.SetValue(1, 4, SudokuValue.NINE);

            var solver = new SudokuSolver.SudokuSolver(puzzle);
            puzzle.ClearBoard();

            Assert.AreEqual(SudokuValue.NINE, solver.Puzzle.GetValue(1, 4));
        }
Пример #11
0
        public void SudokuPuzzle_CanCloneItself()
        {
            var puzzle = new SudokuPuzzle();
            puzzle.SetValue(1, 4, SudokuValue.NINE);
            puzzle.SetValue(2, 3, SudokuValue.FIVE);

            var clone = puzzle.Clone() as SudokuPuzzle;
            puzzle.ClearBoard();

            Assert.AreEqual(SudokuValue.NINE, clone.GetValue(1, 4));
            Assert.AreEqual(SudokuValue.FIVE, clone.GetValue(2, 3));
        }
Пример #12
0
        public void SudokuPuzzle_AllCellsDefaultToSudokuValueUnassigned()
        {
            var puzzle = new SudokuPuzzle();

            for (int i = 0; i < puzzle.CurrentBoard.Length; i++)
            {
                // board is a square...
                for (int j = 0; j < puzzle.CurrentBoard.Length; j++)
                {
                    Assert.AreEqual(SudokuValue.UNASSIGNED, puzzle.CurrentBoard[i][j]);
                }
            }
        }
Пример #13
0
        static void Main(string[] args)
        {
            SudokuPuzzle sp = new SudokuPuzzle();

            //sp.Populate(getSolution(true));
            //sp.Populate(GetPuzzle(10));
            sp = new SudokuPuzzle(SudokuPuzzle.GetPuzzle(@".\Boards\GEOboard.csv"));

            Console.WriteLine(sp.ToString());
            //WritePuzzle(@"K:\MyStuff\Documents\Personal\Sudoku\Output.txt", sp, false);
            WritePuzzle(@".\Output.html", sp);
            Console.ReadLine();
        }
Пример #14
0
        public object Clone()
        {
            var puzzle = new SudokuPuzzle();

            for (int i = 0; i < NUM_ROWS; i++)
            {
                for (int j = 0; j < NUM_ROWS; j++)
                {
                    puzzle.SetValue(i, j, this.GetValue(i, j));
                }
            }

            return puzzle;
        }
Пример #15
0
 private void ReadInClues(SudokuPuzzle puzzle)
 {
     for (int i = 0; i < SUDOKU_DIMENSION; i++)
     {
         for (int j = 0; j < SUDOKU_DIMENSION; j++)
         {
             if (puzzle.PuzzleMatrix[i][j] != 0)
             {
                 ColumnHeader cell = RetrieveHeader(HeaderArrayAccess.Cell, i, j);
                 ColumnHeader row  = RetrieveHeader(HeaderArrayAccess.Row, i, puzzle.PuzzleMatrix[i][j] - 1);
                 AddClues(cell, row);
             }
         }
     }
 }
Пример #16
0
        public static List <SudokuPuzzle> ReadFile(String filename)
        {
            List <SudokuPuzzle> puzzles = new List <SudokuPuzzle>();

            using (StreamReader stream = new StreamReader(new BufferedStream(File.OpenRead(filename))))
            {
                if (stream.EndOfStream)
                {
                    throw new ArgumentException(BAD_FILE_ERRMSG);
                }
                while (!stream.EndOfStream)
                {
                    puzzles.Add(SudokuPuzzle.CreateFromStream(stream));
                }
            }
            return(puzzles);
        }
Пример #17
0
        private static SudokuPuzzle Backtracking(SudokuPuzzle puzzle)
        {
            if (puzzle.IsComplete)
            {
                return(puzzle);
            }

            if (_stopwatch.Elapsed.Minutes >= 5)
            {
                return(null);
            }

            var cell = puzzle.NextCell();

            // Keep track of first three steps
            if (Steps.Count < 3)
            {
                Steps.Add(new SudokuPuzzleStepModel
                {
                    Degree      = puzzle.GetDegree(cell),
                    DomainSize  = cell.Domain.Count,
                    SelectedCol = cell.Col,
                    SelectedRow = cell.Row
                });
            }

            foreach (var value in cell.Domain)
            {
                // Generate next node
                var clone = puzzle.Clone();
                clone.SetCellValue(cell.Row, cell.Col, value);

                // If there exists a cell with an empty domain after forward checking, backtrack
                if (clone.MinRemainingValue()?.Domain.Count == 0)
                {
                    continue;
                }

                var result = Backtracking(clone);
                if (result != null)
                {
                    return(result);
                }
            }
            return(null);
        }
Пример #18
0
        public void Test_DoubleValueColumn()
        {
            SudokuPuzzle puzzle = new SudokuPuzzle();

            puzzle.Cells[0, 1].SetPossibleValues(new[] { 2, 9 });
            puzzle.Cells[0, 2].SetPossibleValues(new[] { 2, 9 });
            foreach (SudokuCell cell in puzzle.GetsSudokuSet(0, SudokuSetType.Column))
            {
                if (cell.X == 0 && (cell.Y == 1 || cell.Y == 2))
                {
                    continue;
                }
                Assert.IsFalse(cell.IsPossible(2), "Cell {0},{1} is not correct: {2}", cell.X, cell.Y, string.Join(",", cell.PossibleValues));
                Assert.IsFalse(cell.IsPossible(9), "Cell {0},{1} is not correct: {2}", cell.X, cell.Y, string.Join(",", cell.PossibleValues));
            }
            string teststr = puzzle.ToString();
        }
Пример #19
0
        public SudokuPuzzle Clone()
        {
            var puzzle = new SudokuPuzzle();

            for (var i = 0; i < 9; i++)
            {
                for (var j = 0; j < 9; j++)
                {
                    Cell cell;
                    if ((cell = GetCell(i, j)).Value != null)
                    {
                        puzzle.SetCellValue(i, j, cell.Value.Value);
                    }
                }
            }
            return(puzzle);
        }
Пример #20
0
        public void SudokuPuzzle_CanClearBoard()
        {
            var puzzle = new SudokuPuzzle();
            puzzle.SetValue(0, 3, SudokuValue.NINE);
            puzzle.SetValue(0, 4, SudokuValue.EIGHT);

            puzzle.ClearBoard();

            for (int i = 0; i < puzzle.CurrentBoard.Length; i++)
            {
                // board is a square...
                for (int j = 0; j < puzzle.CurrentBoard.Length; j++)
                {
                    Assert.AreEqual(SudokuValue.UNASSIGNED, puzzle.CurrentBoard[i][j]);
                }
            }
        }
Пример #21
0
        public static SudokuPuzzle MakeSolvablePuzzle()
        {
            var puzzle = new SudokuPuzzle();

            // set some values
            puzzle.SetValue(0, 0, SudokuValue.EIGHT);
            puzzle.SetValue(0, 2, SudokuValue.FOUR);
            puzzle.SetValue(0, 7, SudokuValue.FIVE);
            puzzle.SetValue(1, 3, SudokuValue.FOUR);
            puzzle.SetValue(1, 6, SudokuValue.SEVEN);
            puzzle.SetValue(1, 8, SudokuValue.SIX);

            puzzle.SetValue(2, 1, SudokuValue.SEVEN);
            puzzle.SetValue(2, 3, SudokuValue.TWO);
            puzzle.SetValue(2, 4, SudokuValue.FIVE);
            puzzle.SetValue(2, 5, SudokuValue.NINE);

            puzzle.SetValue(8, 1, SudokuValue.FOUR);
            puzzle.SetValue(8, 5, SudokuValue.FIVE);
            puzzle.SetValue(8, 8, SudokuValue.SEVEN);

            return puzzle;
        }
Пример #22
0
 public void SudokuPuzzle_GettingValueOutOfBoundsThrowsException()
 {
     var puzzle = new SudokuPuzzle();
     puzzle.GetValue(9, 0);
 }
Пример #23
0
        static void Main(string[] args)
        {
            var puzzle = new SudokuPuzzle();

            puzzle[1, 2] = 8;
            puzzle[1, 3] = 1;
            puzzle[1, 4] = 7;
            puzzle[1, 5] = 9;
            puzzle[1, 7] = 3;
            puzzle[1, 9] = 4;

            puzzle[2, 5] = 4;
            puzzle[2, 8] = 1;
            puzzle[2, 9] = 6;

            puzzle[3, 3] = 6;
            puzzle[3, 4] = 1;
            puzzle[3, 6] = 3;
            puzzle[3, 8] = 5;

            puzzle[4, 6] = 8;
            puzzle[4, 7] = 6;
            puzzle[4, 8] = 4;

            puzzle[5, 3] = 8;
            puzzle[5, 4] = 9;
            puzzle[5, 6] = 4;
            puzzle[5, 7] = 1;

            puzzle[6, 2] = 4;
            puzzle[6, 3] = 9;
            puzzle[6, 4] = 2;

            puzzle[7, 2] = 9;
            puzzle[7, 4] = 6;
            puzzle[7, 6] = 5;
            puzzle[7, 7] = 2;

            puzzle[8, 1] = 8;
            puzzle[8, 2] = 7;
            puzzle[8, 5] = 2;

            puzzle[9, 1] = 2;
            puzzle[9, 3] = 5;
            puzzle[9, 5] = 1;
            puzzle[9, 6] = 7;
            puzzle[9, 7] = 4;
            puzzle[9, 8] = 9;

            //puzzle[1, 2] = 4;
            //puzzle[1, 5] = 1;
            //puzzle[1, 6] = 7;
            //puzzle[1, 8] = 6;

            //puzzle[2, 7] = 5;

            //puzzle[3, 1] = 7;
            //puzzle[3, 3] = 1;
            //puzzle[3, 6] = 8;
            //puzzle[3, 7] = 3;

            //puzzle[4, 1] = 2;
            //puzzle[4, 2] = 1;
            //puzzle[4, 3] = 9;

            //puzzle[5, 2] = 6;
            //puzzle[5, 4] = 7;
            //puzzle[5, 6] = 2;
            //puzzle[5, 8] = 8;

            //puzzle[6, 7] = 6;
            //puzzle[6, 8] = 4;
            //puzzle[6, 9] = 2;

            //puzzle[7, 3] = 4;
            //puzzle[7, 4] = 3;
            //puzzle[7, 7] = 9;
            //puzzle[7, 9] = 7;

            //puzzle[8, 3] = 2;

            //puzzle[9, 2] = 5;
            //puzzle[9, 4] = 2;
            //puzzle[9, 5] = 8;
            //puzzle[9, 8] = 3;

            Console.WriteLine(puzzle);

            var stopWatch = Stopwatch.StartNew();
            var result = puzzle.Solve();
            stopWatch.Stop();

            if (result)
                Console.WriteLine(puzzle);
            else
                Console.WriteLine("Puzzle couldn't be solved");

            Console.WriteLine("Elapsed Time: {0}", stopWatch.ElapsedMilliseconds/1000.0);
        }
Пример #24
0
        public void SudokuPuzzle_ValidatesSameValueInBox()
        {
            var puzzle = new SudokuPuzzle();
            puzzle.SetValue(1, 4, SudokuValue.NINE);

            Assert.IsFalse(puzzle.IsValidValue(SudokuValue.NINE, 2, 3));
        }
Пример #25
0
        private SudokuPuzzle LoadPuzzleState()
        {
            var puzzle = new SudokuPuzzle();

            for (int i = 0; i < this.Cells.Length; i++)
            {
                if (!string.IsNullOrEmpty(this.Cells[i].Text))
                {
                    // mark cell as supplied
                    var row = i / puzzle.CurrentBoard.Length;
                    var col = i % puzzle.CurrentBoard.Length;
                    var value = (SudokuValue)Enum.ToObject(typeof(SudokuValue), int.Parse(this.Cells[i].Text));

                    puzzle.SetValue(row, col, value);
                }
            }

            return puzzle;
        }
Пример #26
0
 public State(SudokuPuzzle puzzle)
     : this(puzzle.Sudoku.Cells.Select(c => new Cell(c, puzzle.Setup.TryGetValue(c, out var value) ? new List <int> { value } : puzzle.Sudoku.Alphabet)))
Пример #27
0
        public void SudokuPuzzle_ValidatesSameValueInRow()
        {
            var puzzle = new SudokuPuzzle();
            puzzle.SetValue(0, 3, SudokuValue.NINE);

            Assert.IsFalse(puzzle.IsValidValue(SudokuValue.NINE, 0, 1));
        }
Пример #28
0
 public void SudokuPuzzle_SettingValueOutOfBoundsThrowsException()
 {
     var puzzle = new SudokuPuzzle();
     puzzle.SetValue(0, 9, SudokuValue.NINE);
 }