Advertisement
Guest User

sudokusolver

a guest
Dec 31st, 2012
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.69 KB | None | 0 0
  1. public class SudokuGroup {
  2.     SudokuCell[] cells;
  3.     int cellCount = 0;
  4.     final int SUDOKUSIZE;
  5.    
  6.     public SudokuGroup(int size, SudokuCell... cells) {
  7.         this.SUDOKUSIZE = size;
  8.         this.cells = new SudokuCell[size];
  9.         //if (cells != null) {
  10.             for (SudokuCell cell : cells) {
  11.                 addCell(cell);
  12.             }
  13.         //}
  14.     }
  15.    
  16.     public void addCell(SudokuCell cell) {
  17.         cell.addParentGroup(this);
  18.         cells[cellCount++] = cell;
  19.     }
  20.    
  21.     void disallow(int number) {
  22.         for (SudokuCell cell : cells) {
  23.             cell.disallow(number);
  24.         }
  25.     }
  26.    
  27.     Boolean tryDetailSolve() {
  28.         for ( int i = 0; i < SUDOKUSIZE; i++ ) {
  29.             SudokuCell onlyCell = null;
  30.             for (SudokuCell cell : cells) {
  31.                 if ( cell.isNumberAllowed(i) ) {
  32.                     if (onlyCell == null) {
  33.                         onlyCell = cell;
  34.                     } else {
  35.                         // second possible placement found, forget it
  36.                         onlyCell = null;
  37.                         break;
  38.                     }
  39.                 }
  40.             }
  41.             if (onlyCell != null && onlyCell.getSolution() == -1 ) {
  42.                 onlyCell.setValue(i);
  43.                 return true;
  44.             }
  45.         }
  46.         return false;
  47.     }
  48.    
  49.    
  50.    
  51. }
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58. public class SudokuCell {
  59.     private Boolean[] numberAllowed;
  60.     private Vector<SudokuGroup> parentGroups = new Vector<SudokuGroup>();
  61.     private int allowedNumberCount;
  62.     private int solution = -1;
  63.    
  64.    
  65.     public SudokuCell(int maxval) {
  66.         numberAllowed = new Boolean[maxval];
  67.         for (int i = 0; i < numberAllowed.length; i++) {
  68.             numberAllowed[i] = true;
  69.         }
  70.         allowedNumberCount = maxval;
  71.     }
  72.    
  73.     void disallow(int number) {
  74.         if ( allowedNumberCount <= 1 || !numberAllowed[number]) {
  75.             return;
  76.         }
  77.         numberAllowed[number] = false;
  78.         allowedNumberCount--;
  79.        
  80.         if ( allowedNumberCount == 1) { // solved
  81.             for (int i = 0; i < numberAllowed.length; i++) {
  82.                 if ( numberAllowed[i] ) {
  83.                     reportSolve(i);
  84.                     return;
  85.                 }
  86.             }
  87.         }
  88.     }
  89.    
  90.     void setValue(int number) {
  91.         for (int i = 0; i < numberAllowed.length; i++) {
  92.             numberAllowed[i] = false;
  93.         }
  94.         numberAllowed[number] = true;
  95.         allowedNumberCount = 1;
  96.         reportSolve(number);
  97.     }
  98.    
  99.     void reportSolve(int solution) {
  100.         this.solution = solution;
  101.         for ( SudokuGroup group : parentGroups ) {
  102.             group.disallow(solution);
  103.         }
  104.     }
  105.    
  106.     Boolean isNumberAllowed(int number) {
  107.         return numberAllowed[number];
  108.     }
  109.    
  110.     void addParentGroup(SudokuGroup group) {
  111.         parentGroups.add(group);
  112.     }
  113.    
  114.     public int getSolution() {
  115.         return solution;
  116.     }
  117.    
  118.    
  119. }
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128. public class Sudokusolver {
  129.     private static final int SUDOKUSIZE = 9;
  130.     private static final int BLOCKSIZE = (int)Math.sqrt(SUDOKUSIZE);
  131.     /**
  132.      * @param args
  133.      */
  134.     public static void main(String[] args) {
  135.         Sudokusolver solver = new Sudokusolver();
  136.  
  137. /* sample input:
  138.  4      1
  139. 67      
  140. 3   2 4 7
  141.    3 6  
  142.    2 4 93
  143. 8 579 2 4
  144. 42    9  
  145.  57 68  
  146.     7   8
  147. */
  148.        
  149.         BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
  150.         for ( int row = 1; row <= SUDOKUSIZE; row++) {
  151.             try {
  152.                 String line = input.readLine();
  153.                 for ( int col = 1; col <= SUDOKUSIZE; col++) {
  154.                     char c = line.charAt(col-1);
  155.                     if (Character.isDigit(c)) {
  156.                         solver.setValue(row, col, new Integer(Character.toString(c)));
  157.                     }
  158.                 }
  159.             } catch (IOException e) {
  160.                 e.printStackTrace();
  161.             }
  162.         }
  163.            
  164.         while (solver.tryDetailSolve()) {
  165.             /*
  166.             System.out.println("=======================================");
  167.             solver.outputAllowed();
  168.             */
  169.         }
  170.        
  171.         solver.outputSolved();
  172.        
  173.     }
  174.    
  175.    
  176.  
  177.     private SudokuCell[][] cells;
  178.     private SudokuGroup[] groups;
  179.    
  180.     public Sudokusolver() {
  181.         cells = new SudokuCell[SUDOKUSIZE][SUDOKUSIZE];
  182.         for (int x = 0; x < SUDOKUSIZE; x++) {
  183.             for (int y = 0; y < SUDOKUSIZE; y++) {
  184.                 cells[x][y] = new SudokuCell(SUDOKUSIZE);
  185.             }
  186.         }
  187.        
  188.         // 0-8: Columns
  189.         // 9-17: Rows
  190.         // 18-26: Blocks
  191.         groups = new SudokuGroup[SUDOKUSIZE*3];
  192.        
  193.         // Columns
  194.         for (int i = 0; i < SUDOKUSIZE; i++) {
  195.             groups[i] = new SudokuGroup(SUDOKUSIZE, cells[i]);
  196.         }
  197.        
  198.         // Rows
  199.         for (int y = 0; y < SUDOKUSIZE; y++) {
  200.             groups[y+9] = new SudokuGroup(SUDOKUSIZE);
  201.             for (int x = 0; x < SUDOKUSIZE; x++) {
  202.                 groups[y+9].addCell(cells[x][y]);
  203.             }
  204.         }
  205.  
  206.         // Blocks
  207.         for (int i = 0; i < SUDOKUSIZE; i++) {
  208.             groups[i+18] = new SudokuGroup(SUDOKUSIZE);
  209.             int blockx = i % BLOCKSIZE;
  210.             int blocky = i / BLOCKSIZE;
  211.             int blockstartx = blockx * BLOCKSIZE;
  212.             int blockstarty = blocky * BLOCKSIZE;
  213.             for (int x = 0; x < BLOCKSIZE; x++) {
  214.                 for (int y = 0; y < BLOCKSIZE; y++) {
  215.                     groups[i+18].addCell(cells[blockstartx+x][blockstarty+y]);
  216.                 }
  217.             }
  218.         }
  219.     }
  220.    
  221.     public void setValue(int row, int column, int value) {
  222.         cells[column-1][row-1].setValue(value-1);
  223.     }
  224.    
  225.     public Boolean tryDetailSolve() {
  226.         for ( SudokuGroup group : groups ) {
  227.             if (group.tryDetailSolve()) {
  228.                 return true;
  229.             }
  230.         }
  231.         return false;
  232.     }
  233.    
  234.     public void outputAllowed() {
  235.         for (int y = 0; y < SUDOKUSIZE; y++) {
  236.             if ( (y % BLOCKSIZE) == 0) {
  237.                 System.out.println("---------------------------------------------------------------------------------------------");
  238.             }
  239.             for (int x = 0; x < SUDOKUSIZE; x++) {
  240.                 if ( (x % BLOCKSIZE) == 0) {
  241.                     System.out.print("|");
  242.                 }
  243.                 for (int number = 0; number < SUDOKUSIZE; number++) {
  244.                     System.out.print(cells[x][y].isNumberAllowed(number)? number+1 : " ");
  245.                 }
  246.                 System.out.print("|");
  247.             }
  248.             System.out.println();
  249.         }
  250.     }
  251.    
  252.    
  253.     public void outputSolved() {
  254.         for (int y = 0; y < SUDOKUSIZE; y++) {
  255.             if ( (y % BLOCKSIZE) == 0) {
  256.                 //System.out.println();
  257.             }
  258.             for (int x = 0; x < SUDOKUSIZE; x++) {
  259.                 if ( (x % BLOCKSIZE) == 0 && (x > 0)) {
  260.                     //System.out.print(" ");
  261.                 }
  262.                 System.out.print(cells[x][y].getSolution() == -1? "?" : cells[x][y].getSolution()+1);
  263.             }
  264.             System.out.println();
  265.         }
  266.     }
  267.  
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement