Android Open Source - SudokuSolver Sudoku Core






From Project

Back to project page SudokuSolver.

License

The source code is released under:

License JSON Sudoku Solver is covered under the Creative Commons Attribution 3.0 Unported License http://creativecommons.org/licenses/by/3.0/ Credits Sudoku Solver Java implementation: Kevin Coulombe...

If you think the Android project SudokuSolver listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * JSON Sudoku solver is covered under the Creative Commons Attribution 3.0 Unported License
 * http://creativecommons.org/licenses/by/3.0/
 * /*from  w  ww .ja v a  2  s  . c o m*/
 * @author: Andrea Bizzotto {@link www.musevisions.com}, {@link www.bizzotto.biz}
 * @email: bizz84dev@gmail.com
 */
package com.musevisions.android.SudokuSolver;


/** Class defining the functionality for verifying and solving Sudoku Puzzles 
 * 
 * This is not Android-specific so it can be easily ported to other projects
 * @author andrea
 *
 */
public class SudokuCore {

  static final int GRID_DIM = 9;
  static final int GRID_SUB_DIM = 3;
  
  static enum SolverMethod {
    SOLVER_BRUTE_FORCE,
    SOLVER_OPTIMISED
  };
  
  /** Array representing the indices (zero-based) of each of the 9 sub-blocks */ 
  static final int SubGridIndices[][] = {
    {  0,  1,  2, 
       9, 10, 11,
      18, 19, 20 },
    {  3,  4,  5, 
      12, 13, 14,
      21, 22, 23 },
    {  6,  7,  8, 
      15, 16, 17,
      24, 25, 26 },

    { 27, 28, 29, 
      36, 37, 38,
      45, 46, 47 },
    { 30, 31, 32, 
      39, 40, 41,
      48, 49, 50 },
    { 33, 34, 35, 
      42, 43, 44,
      51, 52, 53 },

  
    { 54, 55, 56, 
      63, 64, 65,
      72, 73, 74 },
    { 57, 58, 59, 
      66, 67, 68,
      75, 76, 77 },
    { 60, 61, 62, 
      69, 70, 71,
      78, 79, 80 }
  };

  /** Method to check if given puzzle is correct. Verifies that the numbers from 1 to 9 are unique in the following cases:
   * - Unique in all rows
   * - Unique in all columns
   * - Unique in all 3x3 sub-quadrants
   * 
   * @param puzzle array of length 81 representing the input configurations. A value of 0 means not assigned
   * @return error string or null if puzzle is valid
   */
  static public String verify(int puzzle[]) {
    
    /* Rows verification */
    for (int r = 0; r < GRID_DIM; r++) {
      
      int bin[] = initializeBin();
      for (int c = 0; c < GRID_DIM; c++) {
        int value = puzzle[i(r,c)]; 
        if (!updateAndCheck(value, bin)) {
          return "Row " + (r+1) + " is incorrect. " + errorString(value, bin);
        }
      }
    }
    /* Cols verification */
    for (int c = 0; c < GRID_DIM; c++) {
      
      int bin[] = initializeBin();
      for (int r = 0; r < GRID_DIM; r++) {
        int value = puzzle[i(r,c)]; 
        if (!updateAndCheck(value, bin)) {
          return "Col " + (c+1) + " is incorrect. " + errorString(value, bin);
        }
      }
    }
    /* Sub-quadrants verification */
    for (int i = 0; i < GRID_DIM; i++) {
      int bin[] = initializeBin();
      for (int j = 0; j < GRID_DIM; j++) {
        int quadrantIndices[] = SubGridIndices[i]; 
        int value = puzzle[quadrantIndices[j]];
        if (!updateAndCheck(value, bin)) {
          return "Quadrant " + (i+1) + " is incorrect. " + errorString(value, bin);
        }
      }
    }
    
    return null;
  }
  

  
  static private String errorString(int value, int bin[]) {
    return "Element " + value + " found " + bin[value-1] + " times";
  }
  
  static private boolean updateAndCheck(int value, int bin[]) {
    if (value > 0) {
      bin[value-1]++;
      if (bin[value-1] > 1) {
        return false;
      }
    }
    return true;    
  }  

  static private int i(int r, int c) {
    return r * GRID_DIM + c;
  }
  
  /** Initialize a bin with zeros */ 
  static private int[] initializeBin() {
    
    int bins[] = new int [GRID_DIM];
    for (int i = 0; i < GRID_DIM; i++)
      bins[i] = 0;
    return bins;
  }
  
  /** Solving methods */
    public interface SolverListener {
      /** Return false if execution needs to be terminated */
      public boolean onSolverEvent(int result[]);
    }
    /** Wrapper for brute force solver */
    static public int[] solveMethodBruteForce(int puzzle[], SolverListener listener) {
      return SudokuSolverBruteForce.solve(puzzle, listener);
    }
    /** Wrapper for external Sudoku Solver */
    static public int[] solveMethodOptimised(int puzzle[]) {
    
      int board[][] = new int[9][9];
      for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++)
          board[i][j] = puzzle[i*9+j];
      }
      SudokuSolverOptimised.solveBoard(board);
      int output[] = new int[81];
      for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++)
          output[i*9+j] = board[i][j];
      }
      return output;      
    }
    

}




Java Source Code List

com.musevisions.android.SudokuSolver.CustomDialogs.java
com.musevisions.android.SudokuSolver.GridView.java
com.musevisions.android.SudokuSolver.HttpPostUtils.java
com.musevisions.android.SudokuSolver.JSONHelper.java
com.musevisions.android.SudokuSolver.MainTabActivity.java
com.musevisions.android.SudokuSolver.StoreHelper.java
com.musevisions.android.SudokuSolver.SudokuCore.java
com.musevisions.android.SudokuSolver.SudokuLoaderActivity.java
com.musevisions.android.SudokuSolver.SudokuRetrieverTask.java
com.musevisions.android.SudokuSolver.SudokuRetriever.java
com.musevisions.android.SudokuSolver.SudokuSolverActivity.java
com.musevisions.android.SudokuSolver.SudokuSolverBruteForce.java
com.musevisions.android.SudokuSolver.SudokuSolverOptimised.java
com.musevisions.android.SudokuSolver.SudokuSolverTask.java