/// <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); } }
private static void WritePuzzle(string filePath, SudokuPuzzle sp, bool writeHtml = true) { using (StreamWriter sr = new StreamWriter(filePath)) { sr.Write((writeHtml)?sp.ToHTMLString():sp.ToString()); } }
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; }
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 }); }
public void SudokuPuzzle_CanSetValueForCell() { var puzzle = new SudokuPuzzle(); puzzle.SetValue(0, 3, SudokuValue.NINE); Assert.AreEqual(SudokuValue.NINE, puzzle.GetValue(0, 3)); }
/// <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); } } }
private void EnterSolution(Stack <Node> solution, SudokuPuzzle puzzle) { while (solution.Count > 0) { List <ColumnHeader> rowHeaders = solution.Pop().GetLinkedHeaders(); InterpretRow(rowHeaders, puzzle.PuzzleMatrix); } }
public void SolveSudoku(SudokuPuzzle puzzle) { ReadInClues(puzzle); Stack <Node> solution = Search(); EnterSolution(solution, puzzle); RemoveClues(); }
public SudokuSolver(SudokuPuzzle puzzle) { if (puzzle == null) { throw new ArgumentNullException("puzzle"); } this.Puzzle = puzzle.Clone() as SudokuPuzzle; }
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)); }
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)); }
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]); } } }
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(); }
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; }
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); } } } }
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); }
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); }
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(); }
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); }
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]); } } }
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; }
public void SudokuPuzzle_GettingValueOutOfBoundsThrowsException() { var puzzle = new SudokuPuzzle(); puzzle.GetValue(9, 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); }
public void SudokuPuzzle_ValidatesSameValueInBox() { var puzzle = new SudokuPuzzle(); puzzle.SetValue(1, 4, SudokuValue.NINE); Assert.IsFalse(puzzle.IsValidValue(SudokuValue.NINE, 2, 3)); }
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; }
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)))
public void SudokuPuzzle_ValidatesSameValueInRow() { var puzzle = new SudokuPuzzle(); puzzle.SetValue(0, 3, SudokuValue.NINE); Assert.IsFalse(puzzle.IsValidValue(SudokuValue.NINE, 0, 1)); }
public void SudokuPuzzle_SettingValueOutOfBoundsThrowsException() { var puzzle = new SudokuPuzzle(); puzzle.SetValue(0, 9, SudokuValue.NINE); }