2012-03-31 16 views
7

मैं एक एल्गोरिदम कोड करने की कोशिश कर रहा हूं जो जावा या जावास्क्रिप्ट में एक कानूनी सुडोकू बोर्ड बनाता है। न तो काम, और मुझे पूरी तरह से यकीन नहीं है क्यों।सुडोकू जनरेटर के लिए रिकर्सिव समाधान

अनिवार्य रूप से, दोनों कार्यक्रमों में समस्या यह है कि या तो x या y को स्क्वायर छोड़ने से अधिक वृद्धि हो रही है। मैं अपने जीवन के लिए यह नहीं समझ सकता कि यह कैसे हो रहा है। मैं HTML प्रदान कर सकता हूं जो आवश्यक होने पर जेएस समाधान को पूरा करता है।

मेरा सबसे अच्छा अनुमान यह है कि मैंने रिकर्सन का उपयोग करके एक स्टैक कैसे बनाया है, लेकिन जहां तक ​​मैं कह सकता हूं, काम करना चाहिए। मेरे पुराने कोड में लूप के लिए गलत था, मुझे इसके बारे में पता है। मैंने एक पुराना संस्करण चिपकाया, यह अभी तय है।

जावा:

import java.util.*; 

public class SudokuGenerator 
{ 
//credit:cachao 
//http://stackoverflow.com/questions/9959172/recursive-solution-to-sudoku-generator 
public static final int BOARD_WIDTH = 9; 
public static final int BOARD_HEIGHT = 9; 

public SudokuGenerator() { 
    board = new int[BOARD_WIDTH][BOARD_HEIGHT]; 
} 
//Recursive method that attempts to place every number in a square 
public int[][] nextBoard() 
{ 
    nextBoard(0,0); 
    return board; 
} 

public void nextBoard(int x, int y) 
{ 
    int nextX = x; 
    int nextY = y; 
    //int[] toCheck = Collections.shuffle(Arrays.asList({1,2,3,4,5,6,7,8,9})); 
    int[] toCheck = {1,2,3,4,5,6,7,8,9}; 
    Collections.shuffle(Arrays.asList(toCheck)); 

    for(int i=0;i<toCheck.length;i++) 
    { 
     if(legalMove(x, y, toCheck[i])) 
     { 
      board[x][y] = toCheck[i]; 
      if(x == 8) 
      { 
       if(y == 8) 
        break;//We're done! Yay! 
       else 
       { 
        nextX = 0; 
        nextY++; 
       } 
      } 
      else 
      { 
       nextX++; 
      } 
      nextBoard(nextX, nextY); 
     } 
    } 
    board[x][y] = 0; 
} 

public boolean legalMove(int x, int y, int current) { 
    for(int i=0;i<9;i++) { 
     if(current == board[x][i]) 
      return false; 
    } 
    for(int i=0;i<9;i++) { 
     if(current == board[i][y]) 
      return false; 
    } 
    int cornerX = 0; 
    int cornerY = 0; 
    if(x > 2) 
     if(x > 5) 
      cornerX = 6; 
     else 
      cornerX = 3; 
    if(y > 2) 
     if(y > 5) 
      cornerY = 6; 
     else 
      cornerY = 3; 
    for(int i=cornerX;i<10 && i<cornerX+3;i++) 
     for(int j=cornerY;j<10 && j<cornerY+3;j++) 
      if(current == board[i][j]) 
       return false; 
    return true; 
} 

public void print() 
{ 
    for(int i=0;i<9;i++) 
    { 
     for(int j=0;j<9;j++) 
      System.out.print(board[i][j] + " "); 
     System.out.println(); 
    } 
} 

public static void main(String[] args) 
{ 
    SudokuGenerator sg = new SudokuGenerator(); 
    sg.nextBoard(); 
    sg.print(); 
} 
int[][] board; 
} 

जावास्क्रिप्ट:

//Recursive method that attempts to place every number in a square 
function driver() 
{ 
    board = new Array(10); 
    for(var i=0;i<9;i++) 
     board[i] = new Array(10); 
    nextBoard(0,0); 
    print(); 
} 

function nextBoard(x, y) 
{ 
    var nextX = x; 
    var nextY = y; 
    for(var i=1;i<10;i++) { 
     console.log(y + " " + x + " " + i); 
     document.getElementById(y + " " + x).innerHTML = i; 
     if(legalMove(x, y, i)) { 
      board[x][y] = i; 
      if(x === 8) { 
       if(y === 8) 
        return board;//We're done! Yay! 
       else { 
        nextX = 0; 
        nextY++; 
       } 
      } 
      else 
       nextX++; 
      nextBoard(nextX, nextY); 
     } 
    } 
    //This is needed for legalMove to work, otherwise [x][y] == 9 
    board[x][y] = undefined; 
} 

function legalMove(x, y, current) { 
    for(var i=0;i<9;i++) { 
     if(current === board[x][i]) 
      return false; 
    } 
    for(var i=0;i<9;i++) { 
     if(current === board[i][y]) 
      return false; 
    } 
    var cornerX = 0; 
    var cornerY = 0; 
    if(x > 2) 
     if(x > 5) 
      cornerX = 6; 
     else 
      cornerX = 3; 
    if(y > 2) 
     if(y > 5) 
      cornerY = 6; 
     else 
      cornerY = 3; 
    for(var i=cornerX;i<10 && i<cornerX+3;i++) 
     for(var j=cornerY;j<10 && j<cornerY+3;j++) 
      if(current === board[i][j]) 
       return false; 
    return true; 
} 

function print() { 
    for(var i=0;i<9;i++) 
     for(var j=0;j<9;j++) 
     { 
      document.getElementById(i + " " + j).innerHTML = board[i][j]; 
      console.log(board[i][j]);   
     } 
} 

var board; 
+4

एक pastebin के बजाय सवाल में कोड रखो। –

उत्तर

1

जावा के लिए cornerX और cornerY प्रारंभ:

  1. आप अपने board चर को प्रारंभ करना चाहिए, यदि आप एक निर्माता में यह प्रारंभ करने में कर सकते हैं:

    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. मुझे विश्वास है कि समारोह में अपने पाश इटरेटर nextBoard यह गलत है:

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

    मुझे लगता है कि आप 9.

  3. 0 से पुनरावृति करने के लिए समारोह nextBoard में चाहते हैं, तो आप भी चर जांच करने की आवश्यकता:

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

    आप एक java.lang.ArrayIndexOutOfBoundsException मिलता है, आप चाहिए इसे 0 से 8 तक प्रारंभ करें, अन्यथा आप बोर्ड पंक्ति संख्या 9 तक पहुंचने का प्रयास करते हैं और आपको रनटाइम त्रुटि मिलती है।

  4. एक और समस्या जिसे आपको हल करने की आवश्यकता है वह यह है कि एक्स nextBoard() फ़ंक्शन में नौ पर सेट किया जा रहा है। इन parameteres के साथ फंक्शन nextBoard(int x, int y) "मैन्युअल रूप से" कॉल करें: nextBoard(7,3) और आप समझ जाएंगे कि एक्स को नौ पर क्यों सेट किया जा रहा है। विशेष रूप से चर nextX के मानों की जांच करें।

मेरा मानना ​​है कि अगर आप इस तरह की त्रुटियों की जांच करने के लिए एक debugger का उपयोग यह वास्तव में आपकी मदद करेगा, here आप एक वीडियो विवरण के साथ एक अच्छा ट्यूटोरियल है (मामले में अपने ग्रहण आईडीई उपयोग कर रहे हैं)।

उम्मीद है कि यह मदद करता है।

+0

इस त्रुटियों को जांचने का प्रयास करें और फिर एक और विशिष्ट प्रश्न पोस्ट करें। –

+0

मैंने पहले से ही इन त्रुटियों को ठीक कर दिया है। जैसे मैंने कहा, वह पुराना कोड था। यदि आप यह बताना चाहते हैं कि एक्स और/या वाई नौ पर कैसे सेट हो रहे हैं, तो यह बहुत अच्छा होगा! – SomeKittens

+0

बिल्कुल सही @ सोमकिटेंस। मैंने अब अपना प्रश्न अपडेट कर लिया है, मुझे आशा है कि इससे मदद मिलती है। –

1

जावा:

1 से 9 के लिए nextBoard रेंज में आपका पाश इटरेटर मुझे नहीं लगता कि आपको लगता है कि मतलब है। समारोह legalMove में एक ही .... 0.

+0

ओह, ऐसा लगता है जैसे मैंने अपने कोड का पुराना संस्करण चिपकाया। मैं इसे ठीक कर दूंगा। – SomeKittens

0

जावा सरणी अनुक्रमणिका में शून्य-आधारित हैं।nextBoard में 1..9 पर i पर आप toCheck में इंडेक्स के रूप में उपयोग करें जो इंडेक्स 0 पर पहले तत्व को छोड़ देगा और सरणी के अंत से आगे निकल जाएगा। यह ArrayIndexOutOfBoundsException फेंक देगा यदि toCheck[i] वाली रेखा i9 के बराबर है।

+0

मैंने इसे ठीक कर दिया है, लेकिन समस्या अभी भी मौजूद है। ऐसा लगता है कि एक्स और/या वाई किसी भी तरह नौ पर सेट हो रहा है, और मुझे नहीं पता क्यों। – SomeKittens

4

जावा कोड में: मैं 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 

लेकिन क्या अगर आप किसी भी संख्या में नहीं डाल सकते, क्योंकि यह अवैध जा रहा है (उर्फ एक बोर्ड समाप्त होता है जहां आप कर सकते हैं ' किसी विशिष्ट वर्ग में कोई संख्या डालें)?

आप इसे संबोधित नहीं करते हैं। आपको क्या करने की जरूरत है बैक ट्रैकिंग के माध्यम से इसे लागू है:

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

मैं देखता हूं कि आप वहां क्या कर रहे हैं, और मैं समझता हूं। मैंने सोचा कि मैंने इसे पहले से ही एक रिकर्सिव स्टैक का उपयोग करके संभाला था। यदि स्क्वायर पी 4 पर कानूनी था, तो स्क्वायर क्यू पर चले गए, जहां कुछ भी कानूनी नहीं था, क्या रिकर्सन पी पर वापस नहीं आएगा और फिर 5 पर कोशिश करेगा? – SomeKittens

+0

यह नहीं होगा - आपके पास कोड में कोई हिस्सा नहीं है जो बैकट्रैकिंग करता है। समस्या का दिल एक निर्णय है: यदि यह काम करता है, अच्छा, अन्यथा, अगला विकल्प आज़माएं। आपके पास संभालने का कोई खंड नहीं है "क्या होगा यदि मेरा अनुमान कानूनी था, लेकिन मैं इसे वहां से हल नहीं कर सकता?" - जिसका मूल रूप से मतलब है कि आपको वर्तमान बोर्ड को सहेजने की आवश्यकता है, इसे पहले कानूनी अनुमान के साथ आज़माएं, और यदि कोई समाधान नहीं है, तो इसका इलाज करें जैसे कि यह गलत अनुमान था – user1304831

+0

मैंने आपके द्वारा सुझाए गए परिवर्तन किए हैं और समस्या बनी हुई है। मैं अभी भी पूरी तरह से समझ में नहीं आता क्यों, एक असफल रिकर्सिव कॉल के बाद, फ़ंक्शन चलना बंद कर देता है। – SomeKittens

1

दिलचस्प सवाल, मैं सिर्फ देखा जावा कोड में यह एक बग: Collection.shuffle करने के लिए कॉल() बेकार के बाद से toCheck सरणी रहेगा नहीं है इस कॉल के बाद unmodifed (unshuffled)? यहाँ मेरी त्वरित सुधार है (और मुझे यकीन है कि वहाँ यह करने के लिए अधिक चतुर तरीके हैं रहा हूँ):

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); 
+1

वाह, अतीत से क्या विस्फोट होता है। आप सही हैं, हमने पाया कि जैसा कि मैं कक्षा के सामने पेश कर रहा था। शर्मनाक। – SomeKittens

0
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

एक नया नया उत्तर बनाने के बजाय, कृपया अपना पिछला उत्तर अपडेट करें। – Jesse

संबंधित मुद्दे