2012-05-29 5 views
3

나는 이전에 이런 게시물이 몇 개 있다는 것을 알고 있지만, 나를 도와주지 않습니다. 나는 스도쿠를 풀 수있는 프로그램을 작성 중이다. 여기 알고리즘을 찾았습니다 : http://www.heimetli.ch/ffh/simplifiedsudoku.html. 자바로 작성하고 콘솔 기반 프로그램으로 시작하려고합니다. 나는 그것을 막을 방법이 있지만 어떤 이유로 무한 루프에 빠지게됩니다.스도쿠 해답 디버깅

package sudokuSolver; 

public class Solver { 
static int[][] board; //teh board 
static boolean solved;   //if the sudoku is solved 

public static void main(String[] args) throws Exception 
{ 
    //establish temporary board for now 
    final int[][] TUE24JAN = {{0,0,9,0,0,0,8,0,0}, 
           {0,1,0,0,2,0,0,3,0}, 
           {0,0,0,7,0,8,0,0,0}, 
           {2,0,0,0,8,0,0,0,7}, 
           {0,3,0,1,0,2,0,4,0}, 
           {4,0,0,0,7,0,0,0,5}, 
           {0,0,0,6,0,3,0,0,0}, 
           {0,8,0,0,9,0,0,7,0}, 
           {0,0,6,0,0,0,9,0,0},}; 

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

    board = TUE24JAN; 
    solved = false; 
    printBoard(); 

    solve(0,0); 
    System.out.println("\n"); 
    printBoard(); 
} 

public static void solve(int x, int y) throws Exception 
{ 
    //catches the end of the line 
    if(y > 8) 
    { 
     y = 0; 
     x++; 
    } 

    //catches the end of the board 
    if(x > 8 || solved) 
    { 
     solved = true; 
     return; 
    } 
    //put a number in the cell 
    for(int i = 1; i < 10; i++) 
    { 
     if(!inRow(x, i) && !inCol(y, i) && !inBox(x, y, i) && !solved) 
     { 
      board[x][y] = i; 
      solve(x, y+1); 
      board[x][y] = 0; 
     } 
    } 
} 

//returns if the value is in the specified row 
public static boolean inRow(int x, int val) 
{ 
    for(int i = 0; i < 9; i++) 
     if(board[x][i] == val) 
      return true; 
    return false; 
} 

//returns whether the value is in the specified column 
public static boolean inCol(int y, int val) 
{ 
    for(int i = 0; i < 9; i++) 
     if(board[i][y] == val) 
      return true; 
    return false; 
} 

//returns whether the value fits based 
public static boolean inBox(int x, int y, int val) 
{ 
    int row = (x/3) * 3; 
    int col = (y/3) * 3; 
    for(int r = 0; r < 3; r++) 
    for(int c = 0; c < 3; c++) 
     if(board[row+r][col+c] == val) 
      return true; 
    return false; 
} 

public static void printBoard() 
{ 

    for(int i = 0; i < 9; i++) 
    { 
     if(i % 3 == 0) 
      System.out.println("----------------------"); 
     for(int j = 0; j < 9; j++) 
     { 
      if(j % 3 == 0) 
       System.out.print("|"); 
      if(board[i][j] < 10 && board[i][j] > 0) 
       System.out.print(board[i][j] + " "); 
      else 
       System.out.print("- "); 
     } 
     System.out.println("|"); 
    } 
    System.out.print("----------------------\n"); 
} 

}

편집 : 마침내 해결책에 도달하면, 그것은 그것이 더 이상 값을 변경하지 알 수있는 사실에 해결 변경되기 때문에 그것은 세포를 취소하지 않아야합니다. 스택 오버플로 오류가 발생하지 않고 계속 실행됩니다. 나는 실수로 1 시간 동안 작동하게하고 여전히 실행 중이었고, 한 지점에서 계속 반복되고, 해결 된 상태에 도달하지 않았고 첫 번째 반복적 인 순서에 결코 충돌하지 않았습니다.

단계별 디버깅은 어떻게 할 수 있습니까? 이클립스를 사용하지만, 라인 단위로 라인을 수행 할 수있게 해주는 다른 IDE가 있다면 말해 줄 수 있습니까?

+2

당신이 무한 루프를 얻을 이유를 알아 내려고 시도하는 단계에서 프로그램 단계 디버깅을 시도 해 봤나 : 디버깅하지 않고 있지만, 약간의 로깅과 내가 위에 언급 한 몇 가지 좋은 의견 이 함께했다? – assylias

+0

@trutheality 그는 행을 증가시킬 최상위'x ++; '근처의 solve 메소드에 있습니다. 나는 그가 'solve (x, y);를 필요로한다고 생각한다. 그러나 그 시점에서 ... 나는 모든 코드를 추적하지는 못했다. – Shaded

+0

@ 음영 잘 잡습니다. 그것은 그 때 작동해야하는 것처럼 보인다. 이 경우 무한 재귀가 어디서 발생하는지 확실하지 않습니다 ... – trutheality

답변

1

위의 코드 샘플은 글로벌 solved 변수에 대한 재귀 가능성을 최대한으로 활용하지 않습니다. 나는 처음부터 해결책을 만들지 않았지만 당신이 제시 한 것을 고쳐서 차이점을 볼 수 있도록 노력했습니다. 의심스러운 점이 있으면 의견을 말하십시오.

package sudoku; 

public class Solver { 
    static int[][] board; //teh board 
    static boolean solved; //if the sudoku is solved 

    public static void main(String[] args) throws Exception { 

     //establish temporary board for now 
     final int[][] TUE24JAN = 
      { 
       {0, 0, 9, 0, 0, 0, 8, 0, 0}, 
       {0, 1, 0, 0, 2, 0, 0, 3, 0}, 
       {0, 0, 0, 7, 0, 8, 0, 0, 0}, 

       {2, 0, 0, 0, 8, 0, 0, 0, 7}, 
       {0, 3, 0, 1, 0, 2, 0, 4, 0}, 
       {4, 0, 0, 0, 7, 0, 0, 0, 5}, 

       {0, 0, 0, 6, 0, 3, 0, 0, 0}, 
       {0, 8, 0, 0, 9, 0, 0, 7, 0}, 
       {0, 0, 6, 0, 0, 0, 9, 0, 0}, 
      }; 

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

     board = TUE24JAN; 
     solved = false; 
     printBoard(); 

     solve(0, 0); 
     System.out.println("\n"); 
     printBoard(); 
    } // end method main 

    public static void solve(int x, int y) throws Exception { 

     //printBoard(); 
     System.out.println(x + " : " + y); 

     //catches the end of the line 
     if (y > 8) { 
      y = 0; 
      x++; 
     } 

     //catches the end of the board 
     if ((x > 8) || solved) { 
      solved = true; 
      return; 
     } 

     //put a number in the cell 
     for (int i = 1; i < 10; i++) { 

      if ((board[x][y] == 0)) { // cell to be filled 

       if (!inRow(x, i) && !inCol(y, i) && !inBox(x, y, i)) { // can use number 

        board[x][y] = i; 

        solve(x, y + 1); 

        if (solved) { 
         return; 
        } 

        board[x][y] = 0; 

       } 
      } 
      else { 
       solve(x, y + 1); 

       return; 

      } 
     } // end for 
    } // end method solve 

    //returns if the value is in the specified row 
    public static boolean inRow(int x, int val) { 

     for (int i = 0; i < 9; i++) { 

      if (board[x][i] == val) { 
       return true; 
      } 
     } 

     return false; 
    } 

    //returns whether the value is in the specified column 
    public static boolean inCol(int y, int val) { 

     for (int i = 0; i < 9; i++) { 

      if (board[i][y] == val) { 
       return true; 
      } 
     } 

     return false; 
    } 

    //returns whether the value fits based 
    public static boolean inBox(int x, int y, int val) { 
     int row = (x/3) * 3; 
     int col = (y/3) * 3; 

     for (int r = 0; r < 3; r++) { 

      for (int c = 0; c < 3; c++) { 

       if (board[row + r][col + c] == val) { 
        return true; 
       } 
      } 
     } 

     return false; 
    } 

    public static void printBoard() { 
     StringBuilder sb = new StringBuilder(); 

     for (int i = 0; i < 9; i++) { 

      if ((i % 3) == 0) { 
       sb.append("----------------------\n"); 
      } 

      for (int j = 0; j < 9; j++) { 

       if ((j % 3) == 0) { 
        sb.append("|"); 
       } 

       if ((board[i][j] < 10) && (board[i][j] > 0)) { 
        sb.append(board[i][j] + " "); 
       } 
       else { 
        sb.append("- "); 
       } 
      } 

      sb.append("|\n"); 
     } 

     sb.append("----------------------\n"); 
     System.out.println(sb.toString()); 

     /*try { 
      Thread.sleep(100); 
     } 
     catch (InterruptedException e) { 

      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     }*/ 
    } // end method printBoard 
} // end class Solver 
+1

+1하지만 "for 루프에서 solve()를 호출 한 후 해결 된 조건을 확인하고 true이면 반환"이라고 말할 수 있습니다. ... 몇 분 동안 코드를 읽고 비교하여 정확히 다른 않았다. – Kevin

+0

잘 다시 시작한 케빈 – Zecas