Recursive solution to Sudoku generator

后端 未结 6 926
青春惊慌失措
青春惊慌失措 2020-12-19 05:14

I\'m trying to code an algorithm that creates a legal Sudoku board in either Java or Javascript. Neither work, and I\'m not entirely sure why.

Essentially, the prob

相关标签:
6条回答
  • 2020-12-19 05:55

    Java:

    Your loop iterator in nextBoard range from 1 to 9. I don't think you meant that. Same in the function legalMove.... initialize cornerX and cornerY to 0.

    0 讨论(0)
  • 2020-12-19 06:03

    In Java array indexes are zero-based. In nextBoard you loop over 1..9 for i and use it as an index into toCheck which will skip the first element at index 0 and go past the end of the array. This will throw ArrayIndexOutOfBoundsException if the line containing toCheck[i] is reached with i equal to 9.

    0 讨论(0)
  • 2020-12-19 06:05

    interesting question, I just noticed this one bug in the Java code: isn't the call to Collection.shuffle() useless since the toCheck array will remain unmodifed (unshuffled) after this call? Here is my quick fix (and I'm sure there are more clever ways to do it):

    List<Integer> lst = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    Collections.shuffle(lst);
    for (int i=0; i<lst.size(); i++)
        toCheck[i] = lst.get(i);
    
    0 讨论(0)
  • 2020-12-19 06:19

    Java:

    1. You should initialize your board variable, you may want to initialize it in a constructor:

      public class SudokuGenerator {
      
          public static final int BOARD_WIDTH = 9;
          public static final int BOARD_HEIGHT = 9;
      
          public SudokuGenerator() {
              board = new int[BOARD_WIDTH][BOARD_HEIGHT];
          }
      }
      
    2. I believe that your loop iterator in the function nextBoard it is wrong:

      for(int i=1;i<10;i++){ ... }

      I think that you want to iterate from 0 to 9.

    3. In the function nextBoard, you also need to check the variable:

      int[] toCheck = {1,2,3,4,5,6,7,8,9};

      You get an java.lang.ArrayIndexOutOfBoundsException, you should initialize it from 0 to 8, otherwise you try to access the board row number 9 and you get a runtime error.

    4. Another problem that you need to solve is that x is being set to nine in nextBoard() function. Call the function nextBoard(int x, int y) "manually" with these parameteres: nextBoard(7,3) and you will understand why x is being set to nine. Check specifically the values of the variable nextX.

    I believe it will really help you if you use a debugger to check this kind of errors, here you have a nice tutorial with a video explanation(in case your are using the Eclipse IDE).

    Hope it helps.

    0 讨论(0)
  • 2020-12-19 06:19

    In the Java code: I'll translate it to psuedocode:

    for all z values:
        If for current (x,y), the number 'z' is legal then:
            insert z to current (x,y)
            if finished
                hooray!
            else 
                go to next square
        else try next number
    

    But what if you can't put any number there as it ends up being illegal (aka a board where you can't insert any number in a specific square)?

    You don't address that. What you need to do is implement it via backtracking:

    for all z values:
        If for current (x,y) the number 'z' is legal then:
            insert z to current (x,y)
            go to next(x,y)
                try to complete the board    // recursive call
            if you completed the board       // == the result of the recursion is legal
                return the completed board
        If all z values have been attempted
            return "cannot complete board"
        increment z, try again with current (x,y)
    
    0 讨论(0)
  • 2020-12-19 06:19
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.util.Arrays;
    import java.util.Scanner;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    
    public class SudokuNrupen {
    
         public static int[][] p;
         public static int tmp[] ;
         public static int tmp2D[][] ;
    
    
        public static void main(String[] args){
    
            tmp = new int[9];
            tmp2D = new int[3][3];
            p = new int[9][9];
    
             System.out.print("Enter the name of he file below ");
             Scanner scan = new Scanner (System.in);
             String name = scan.nextLine();
             File file = new File( name );
    
             if ( file.exists()){   
                try {
                    Scanner inFile = new Scanner( file );
                    for(int i=0; i<9; i++){
                         for(int j=0; j<9; j++){
                             if(inFile.hasNextInt()){
                                 p[i][j] = inFile.nextInt();
                             }
                         }
                     }   
                inFile.close();
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(SudokuNrupen.class.getName()).log(Level.SEVERE, null, ex);
                }
           }
    
          display(p);
          solve(p);
          System.out.println("Solved Sudoku is:");
          display(p);      
    
    
         }
    
         public static void display(int [][] p)
        {
            for(int i=0; i<p.length;i++)
            {
                for(int j=0; j<p[i].length;j++)
                {
                    System.out.print("   ");
                    if(p[i][j]<10)     System.out.print(p[i][j] + " ");
                    else                    System.out.print(p[i][j]);
                    System.out.print("  ");
                }
                System.out.println();
            }    
        }  
    
        public static boolean solve(int [][] p)
        {
            if(!isValidSudoku(p))
            {
                 return false;
            }
            if(isComplete(p)==true)
            {
                return true;
            }
            for(int i=0; i<9; i++)
            {
                for(int j=0 ; j<9 ; j++)
                {
                    if(p[i][j]==0) 
                    {
                        int k=1;
                        while(k<=9)
                        {
                            p[i][j]=k;
                            if(solve(p))
                            {
                                return true;
                            }
                            else    k++;
                        }    
                        p[i][j]=0; 
                        return false; 
                    }
                }
            }
            return true;
        }
    
    
        public static boolean isComplete(int [][]p)
        {
            for(int i=0; i<9; i++)
            {
                for(int j=0 ; j<9 ; j++)
                {
                    if(p[i][j]==0){
                        return false;
                    }
                }
            }
            return true;
        }    
    
    
        public static boolean isRepeated(int [] a)
        {
            for(int i=0; i<8; i++)
            {
                if((a[i]!=0 || a[i+1]!=0))
                {
                         if(a[i]==a[i+1]){
                             return true;
                         }
                }  
            }
            return false;    
        }
    
    
     public static boolean isDuplicateEx0(int [][]p)
        {
    
            for(int i=0; i<p[0].length; i++)
            {
                for(int j=0 ; j<9 ; j++)
                {
                    tmp[j]=p[i][j];
                }
                Arrays.sort(tmp);
    
                System.out.println(Arrays.toString(tmp));
    
                if(isRepeated(tmp)==true)
                {
                    System.out.println("Duplicates are found in row");
                    return true;
                }
    
            }
    
            display(p);
            for(int j=0; j<p[0].length; j++)
            {
                for(int i=0 ; i<9 ; i++)
                {
                    tmp[i]=p[i][j];
                }
                Arrays.sort(tmp);
    
                if(isRepeated(tmp)==true)
                {
                    System.out.println("Duplicates are found in columns");
                    return true;
                }
    
            }
    
            display(p);
    
            for(int z=0;z<9;z++){
                tmp[z]=0;
            }
    
            int x=0,y=0;
    
            for(int i=0; i<3;i++)
            {   
                y=0;
                for(int j=0;j<3;j++)
                {
                    tmp2D[x][y]=p[i][j];
                    y++;
                }
                x++;
            }
            for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
                {
                    tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
                }
            }
            Arrays.sort(tmp);
            if(isRepeated(tmp)==true)
            {
                return true;
            }
    
            for(int z=0;z<9;z++){
                tmp[z]=0;
            }
            x=0;
            y=0;
    
            for(int i=0; i<3;i++)
            {   
                y=0;
                for(int j=3;j<6;j++)
                {
                    tmp2D[x][y]=p[i][j];
                    y++;
                }
                x++;
            }
            for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
                {
                    tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
                }
            }
            Arrays.sort(tmp);
            if(isRepeated(tmp)==true)
            {
                return true;
            }
    
    
            for(int z=0;z<9;z++){
                tmp[z]=0;
            }
            x=0;
            y=0;
    
            for(int i=0; i<3;i++)
            {   
                y=0;
                for(int j=6;j<9;j++)
                {
                    tmp2D[x][y]=p[i][j];
                    y++;
                }
                x++;
            }
            for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
                {
                    tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
                }
            }
            Arrays.sort(tmp);
            if(isRepeated(tmp)==true)
            {
                return true;
            }
    
            for(int z=0;z<9;z++){
                tmp[z]=0;
            }
            x=0;
            y=0;
    
            for(int i=3; i<6;i++)
            {   
                y=0;
                for(int j=0;j<3;j++)
                {
                    tmp2D[x][y]=p[i][j];
                    y++;
                }
                x++;
            }
            for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
                {
                    tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
                }
            }
            Arrays.sort(tmp);
            if(isRepeated(tmp)==true)
            {
                return true;
            }
    
            for(int z=0;z<9;z++){
                tmp[z]=0;
            }
            x=0;
            y=0;
    
            for(int i=3; i<6;i++)
            {   
                y=0;
                for(int j=3;j<6;j++)
                {
                    tmp2D[x][y]=p[i][j];
                    y++;
                }
                x++;
            }
            for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
                {
                    tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
                }
            }
            Arrays.sort(tmp);
            if(isRepeated(tmp)==true)
            {
                return true;
            }
    
            for(int z=0;z<9;z++){
                tmp[z]=0;
            }
            x=0;
            y=0;
    
            for(int i=3; i<6;i++)
            {   
                y=0;
                for(int j=6;j<9;j++)
                {
                    tmp2D[x][y]=p[i][j];
                    y++;
                }
                x++;
            }
            for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
                {
                    tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
                }
            }
            Arrays.sort(tmp);
            if(isRepeated(tmp)==true)
            {
                return true;
            }
    
            for(int z=0;z<9;z++){
                tmp[z]=0;
            }
            x=0;
            y=0;
    
            for(int i=6; i<9;i++)
            {   
                y=0;
                for(int j=0;j<3;j++)
                {
                    tmp2D[x][y]=p[i][j];
                    y++;
                }
                x++;
            }
            for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
                {
                    tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
                }
            }
            Arrays.sort(tmp);
            if(isRepeated(tmp)==true)
            {
                return true;
            }
    
            for(int z=0;z<9;z++){
                tmp[z]=0;
            }
            x=0;
            y=0;
    
            for(int i=6; i<9;i++)
            {   
                y=0;
                for(int j=3;j<6;j++)
                {
                    tmp2D[x][y]=p[i][j];
                    y++;
                }
                x++;
            }
            for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
                {
                    tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
                }
            }
            Arrays.sort(tmp);
            if(isRepeated(tmp)==true)
            {
                return true;
            }
    
            for(int z=0;z<9;z++){
                tmp[z]=0;
            }
            x=0;
            y=0;
    
            for(int i=6; i<9;i++)
            {   
                y=0;
                for(int j=6;j<9;j++)
                {
                    tmp2D[x][y]=p[i][j];
                    y++;
                }
                x++;
            }
            for(int i=0; i<3; i++)
            {
                for(int j=0; j<3; j++)
                {
                    tmp[(i*tmp2D.length) + j] = tmp2D[i][j];
                }
            }
            Arrays.sort(tmp);
            if(isRepeated(tmp)==true)
            {
                return true;
            }
    
    
            return false;
        }
    
    
    
         public static boolean isValidSudoku(int [][] p)
         {
               return (!isDuplicateEx0(p));  
         }
    }
    
    0 讨论(0)
提交回复
热议问题