/// <summary> /// Solves the grid in-place. /// </summary> /// <param name="grid"> /// The grid to solve. This grid will be modified to contain the solution to /// the sudoku puzzle, if it exists. /// </param> /// <returns> /// If the puzzle can be unambiguously solved, Solve() will return true. /// If the puzzle cannot be solved or has more than one solution, /// this will return false. /// </returns> public bool Solve(Grid grid) { int numSolutions = 0; Grid solutionGrid = grid.Copy(); if (FindErrors(grid).Count > 0) { // fail fast! return(false); } // this bit here GREATLY simplifies DepthFirstSearch. // Using exceptions and a lambda to terminate after two // solutions frees DepthFirstSearch from worrying about // all that logic at the cost of a closure and tricky // exception handling. // all of this is to avoid C#'s lack of generators, buh try { DepthFirstSearch(grid, () => { // this lambda gets run on each solution numSolutions++; solutionGrid = grid.Copy(); if (numSolutions > 1) { throw new StopIterationException(); } }); } catch (StopIterationException e) { } // (just pretend that empty catch block is a generator) grid.CopyFrom(solutionGrid); return(numSolutions == 1); }
/// <summary> /// Solves the grid in-place. /// </summary> /// <param name="grid"> /// The grid to solve. This grid will be modified to contain the solution to /// the sudoku puzzle, if it exists. /// </param> /// <returns> /// If the puzzle can be unambiguously solved, Solve() will return true. /// If the puzzle cannot be solved or has more than one solution, /// this will return false. /// </returns> public bool Solve(Grid grid) { int numSolutions = 0; Grid solutionGrid = grid.Copy(); if (FindErrors(grid).Count > 0) { // fail fast! return false; } // this bit here GREATLY simplifies DepthFirstSearch. // Using exceptions and a lambda to terminate after two // solutions frees DepthFirstSearch from worrying about // all that logic at the cost of a closure and tricky // exception handling. // all of this is to avoid C#'s lack of generators, buh try { DepthFirstSearch(grid, () => { // this lambda gets run on each solution numSolutions++; solutionGrid = grid.Copy(); if (numSolutions > 1) { throw new StopIterationException(); } }); } catch (StopIterationException e) { } // (just pretend that empty catch block is a generator) grid.CopyFrom(solutionGrid); return numSolutions == 1; }