2016-03-17 2 views
1

Я написал javascript программу для решения sudoku. Кажется, он работает, но затем он внезапно останавливается. Console shows that it is working but suddenly stops for no reasonЯвляется ли мой javascript грубой силой рекурсии Судоку-решателю не хватает памяти?

Это причина? : (Timeline) Я новичок в javascript, что я могу сделать, чтобы исправить это?

Как исправить это? благодаря!

Вот код:

<html> 
 

 
<head> 
 
</head> 
 

 
<body> 
 
    <script> 
 
    var game = [ 
 
     [0, 0, 9, 0, 5, 7, 0, 6, 0], 
 
     [0, 7, 0, 6, 0, 0, 0, 0, 0], 
 
     [8, 0, 0, 0, 1, 0, 7, 5, 0], 
 
     [0, 0, 0, 3, 6, 0, 1, 7, 2], 
 
     [4, 1, 2, 0, 0, 0, 6, 9, 3], 
 
     [6, 3, 7, 0, 2, 9, 0, 0, 0], 
 
     [0, 4, 1, 0, 5, 0, 0, 0, 7], 
 
     [0, 0, 0, 0, 0, 3, 0, 8, 0], 
 
     [0, 5, 0, 2, 9, 0, 4, 0, 0] 
 
    ]; 
 

 
    function solve(x, y, g) { 
 
     var nextx; 
 
     var nexty = y; 
 
     if (x < 9 || y < 9) { 
 
     if (g[x][y] == 0) { 
 
      for (i = 1; i < 10; i++) { 
 
      g[x][y] = i; 
 
      if (check(x, y, i, g) == true) { 
 
       if (x < 8) { 
 
       nextx = x + 1; 
 
       } else { 
 
       nexty = y + 1; 
 
       nextx = 0; 
 
       } 
 
       console.log(x + ' ' + y + ' ' + i + ' ' + g[x][y]); 
 
       solve(nextx, nexty, g); 
 
      } else { 
 
       if (x != 0 && y != 0) { 
 
       return; 
 
       } 
 
      } 
 
      } 
 
     } else { 
 
      if (x < 8) { 
 
      nextx = x + 1; 
 
      } else { 
 
      nexty = y + 1; 
 
      nextx = 0; 
 
      } 
 
      console.log(x + ' ' + y + ' ' + 'b' + ' ' + g[x][y]); 
 
      solve(nextx, nexty, g); 
 
      return; 
 
     } 
 
     } else { 
 
     if (checkall(g) == true) { 
 
      for (var i = 0; i < 9; i++) { 
 
      document.write(g[i] + '</br>'); 
 
      }; 
 
     } else { 
 
      document.write("can't solve"); 
 
     } 
 
     } 
 
    } 
 

 
    function check(x, y, i, g) { 
 
     var tempx = 0; 
 
     var tempy = 0; 
 
     var tempb = 0; 
 
     var a, b; 
 

 
     for (j = 0; j < 9; j++) { 
 
     if (g[x][j] == i) { 
 
      tempx = tempx + 1; 
 
     } 
 
     if (g[j][y] == i) { 
 
      tempy = tempy + 1; 
 
     } 
 
     } 
 

 
     if (x < 3) { 
 
     a = 0; 
 
     } 
 
     if (x < 6) { 
 
     a = 3; 
 
     } 
 
     if (x < 9) { 
 
     a = 6; 
 
     } 
 
     if (y < 3) { 
 
     b = 0; 
 
     } 
 
     if (y < 6) { 
 
     b = 3; 
 
     } 
 
     if (y < 9) { 
 
     b = 6; 
 
     } 
 

 
     for (c = a; c < a + 3; c++) { 
 
     for (d = b; d < b + 3; d++) { 
 
      if (g[a][b] == i) { 
 
      tempb = tempb + 1; 
 
      } 
 
     } 
 
     } 
 

 
     if (tempx > 1 || tempy > 1 || tempb > 1) { 
 
     return false; 
 
     } else { 
 
     return true; 
 
     } 
 

 
    } 
 

 
    function checkall(g) { 
 
     var temp1 = 0; 
 
     var temp2 = 0; 
 
     for (var i = 0; i < 10; i++) { 
 
     for (var x = 0; x < 9; x++) { 
 
      for (var y = 0; y < 9; y++) { 
 
      if (g[x][y] == i) { 
 
       temp1 = temp1 + 1; 
 
      } 
 
      if (g[y][x] == i) { 
 
       temp2 = temp2 + 1; 
 
      } 
 
      }; 
 
      if (temp1 > 1 || temp2 > 1) { 
 
      return false; 
 
      } else { 
 
      temp1 = 0; 
 
      temp2 = 0; 
 
      } 
 
     } 
 
     } 
 
     return true 
 
    } 
 

 
    solve(0, 0, game); 
 
    </script> 
 
    </div> 
 
</body> 
 

 
</html>

+0

Просто предложение, но почему бы вам не сделать массив «игра» и объект, а функции решить и проверить методы объекта «игра». – SPlatten

+0

Я новичок в объектах, это поможет в любом случае? –

+0

Это означает, что вы можете обернуть все в объекте, инкапсулирующем все функции, и не нужно передавать данные во все. – SPlatten

ответ

0

Убедитесь, что вы проверить ответы, возвращаемые из функций:

var div = document.getElementById('output'); 

потерпит неудачу и DIV будет 'не определено', потому что вы не имеют тега открытия div в вашем примере с идентификатором «output».

Если вы добавите предложения try/catch в свои функции, вы увидите сообщения об ошибках.

Я вижу, что вы фактически не используете «div» в своем коде.

Я только изменил код немного, как я не получаю ошибки, когда я запускаю его:

<html> 
    <body> 
     <script> 
     var game = [ 
      [0, 0, 9, 0, 5, 7, 0, 6, 0], 
      [0, 7, 0, 6, 0, 0, 0, 0, 0], 
      [8, 0, 0, 0, 1, 0, 7, 5, 0], 
      [0, 0, 0, 3, 6, 0, 1, 7, 2], 
      [4, 1, 2, 0, 0, 0, 6, 9, 3], 
      [6, 3, 7, 0, 2, 9, 0, 0, 0], 
      [0, 4, 1, 0, 5, 0, 0, 0, 7], 
      [0, 0, 0, 0, 0, 3, 0, 8, 0], 
      [0, 5, 0, 2, 9, 0, 4, 0, 0] 
     ]; 
     var intNestedCalls = 0; 
     function solve(x, y, g) { 
      var nextx; 
      var nexty = y; 
      intNestedCalls++; //Count numer of nested calls 
      if (x < 9 || y < 9) { 
      if (g[x][y] == 0) { 
       for (i = 1; i < 10; i++) { 
       g[x][y] = i; 
       if (check(x, y, i, g) == true) { 
        if (x < 8) { 
        nextx = x + 1; 
        } else { 
        nexty = y + 1; 
        nextx = 0; 
        } 
        console.log(x + ' ' + y + ' ' + i + ' ' + g[x][y]); 
        solve(nextx, nexty, g); 
       } else { 
        if (x != 0 && y != 0) { 
    //Break here so we drop out and exit the function    
        break; 
        } 
       } 
       } 
      } else { 
       if (x < 8) { 
       nextx = x + 1; 
       } else { 
       nexty = y + 1; 
       nextx = 0; 
       } 
       console.log(x + ' ' + y + ' ' + 'b' + ' ' + g[x][y]); 
       solve(nextx, nexty, g); 
    //No need to return here, fall through and exit normally 
    //  return;     
      } 
      } else { 
      if (checkall(g) == true) { 
       for (var i = 0; i < 9; i++) { 
       document.write(g[i] + '</br>'); 
       }; 
      } else { 
       document.write("can't solve"); 
      } 
      } 
      intNestedCalls--; //Update nested call counter 
     } 
     function check(x, y, i, g) { 
      var tempx = 0; 
      var tempy = 0; 
      var tempb = 0; 
      var a, b; 
      for (j = 0; j < 9; j++) { 
      if (g[x][j] == i) { 
       tempx = tempx + 1; 
      } 
      if (g[j][y] == i) { 
       tempy = tempy + 1; 
      } 
      } 
      if (x < 3) { 
      a = 0; 
      } 
      if (x < 6) { 
      a = 3; 
      } 
      if (x < 9) { 
      a = 6; 
      } 
      if (y < 3) { 
      b = 0; 
      } 
      if (y < 6) { 
      b = 3; 
      } 
      if (y < 9) { 
      b = 6; 
      } 
      for (c = a; c < a + 3; c++) { 
      for (d = b; d < b + 3; d++) { 
       if (g[a][b] == i) { 
       tempb = tempb + 1; 
       } 
      } 
      } 
      if (tempx > 1 || tempy > 1 || tempb > 1) { 
      return false; 
      } else { 
      return true; 
      } 
     } 
     function checkall(g) { 
      var temp1 = 0; 
      var temp2 = 0; 
      for (var i = 0; i < 10; i++) { 
      for (var x = 0; x < 9; x++) { 
       for (var y = 0; y < 9; y++) { 
       if (g[x][y] == i) { 
        temp1 = temp1 + 1; 
       } 
       if (g[y][x] == i) { 
        temp2 = temp2 + 1; 
       } 
       }; 
       if (temp1 > 1 || temp2 > 1) { 
       return false; 
       } else { 
       temp1 = 0; 
       temp2 = 0; 
       } 
      } 
      } 
      return true; 
     } 
     solve(0, 0, game);  
    alert("Complete!");  
     </script> 
     </div> 
    </body> 
    </html> 

Я не вижу никакого выхода на все, кроме полной! после короткого периода.

Логика никогда не будет вашим инструкциям «document.write», потому что х и у ваша логика будет только к высказываниям записи, если х и у> = 9.

Если ваше испытание быть:

if (x < 9 && y < 9) { 
+0

, который тестировался до того, как я случайно остался там. он ничего не делает. –

+0

wont this output result? для (var i = 0; i <9; i ++) { документ.написать (g [i] + '
'); }; –

+0

Нет, потому что ваша логика не правильная, и она никогда не доберется! – SPlatten

Смежные вопросы