数独求解器适用于 python 但不适用于 javascript
Sudoku solver works in python but not javascript
所以我一直在关注关于编写数独求解器的 Computerphile 视频,并设法让代码在 python 中运行,这就是我得到的结果:
def possible(grid, y, x, n):
for i in range(0,9):
if grid[y][i] == n:
return False
if grid[i][x] == n:
return False
x0 = (x//3)*3
y0 = (y//3)*3
for i in range(0,3):
for j in range(0,3):
if grid[y0+i][x0+j] == n:
return False
return True
def solver(grid):
for y in range(9):
for x in range(9):
if grid[y][x] == 0:
for n in range(1,10):
if possible(grid, y, x, n):
grid[y][x] = n
solver(grid)
grid[y][x] = 0
return
print(np.matrix(grid))
这段代码工作正常。但是我想尝试让它在网络应用程序中工作,所以我将它翻译成 Javascript 像这样:
function possible(board, y, x, n) {
for(i = 0; i < 9; i++) {
if(board[y][i] === n) {
return false;
}
if(board[i][x] === n) {
return false;
}
}
y0 = Math.floor(y/3)*3;
x0 = Math.floor(x/3)*3;
for(i = 0; i < 3; i++) {
for(j = 0; j < 3; j++) {
if(board[i+y0][j+x0] === n) {
return false;
}
}
}
return true;
}
function solver(board) {
for(y = 0; y < 9; y++) {
for(x = 0; x < 9; x++) {
if(board[y][x] === 0) {
for(n = 1; n < 10; n++) {
if(possible(board, y, x, n)) {
board[y][x] = n;
solver(board);
board[y][x] = 0;
}
}
return;
}
}
}
console.log(board);
}
据我所知,这些功能完全相同,而且由于它在 Python 中有效,所以我不明白为什么它在 JavaScript 中不起作用。在 JS 中,它似乎从来没有达到 console.log(board) 线,所以我正在徘徊,如果我达到最大递归深度或类似的简单东西。
作为参考,这是在 Python 求解器中工作的网格:
grid = [
[5, 3, 0, 0, 7, 0, 0, 0, 0],
[6, 0, 0, 1, 9, 5, 0, 0, 0],
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1],
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0],
[0, 0, 0, 4, 1, 9, 0, 0, 5],
[0, 0, 0, 0, 8, 0, 0, 7, 9]
]
如果您在函数内使用 for 循环,var
将创建一个局部变量,“no var”将查找作用域链,直到找到该变量或到达全局作用域。
这意味着您需要在 for 循环内创建变量时声明 var
以避免一个循环与另一个循环混淆。阅读更多 here
因此您的代码应如下所示:
function possible(board, y, x, n) {
for (var i = 0; i < 9; i++) {
if (board[y][i] === n) {
return false;
}
if (board[i][x] === n) {
return false;
}
}
y0 = Math.floor(y / 3) * 3;
x0 = Math.floor(x / 3) * 3;
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
if (board[y0+i][x0+j] === n) {
return false;
}
}
}
return true;
}
function solver(board) {
for (var y = 0; y < 9; y++) {
for (var x = 0; x < 9; x++) {
if (board[y][x] === 0) {
for (var n = 1; n < 10; n++) {
if (possible(board, y, x, n)) {
board[y][x] = n;
solver(board);
board[y][x] = 0;
}
}
return
}
}
}
console.log(board);
}
所以我一直在关注关于编写数独求解器的 Computerphile 视频,并设法让代码在 python 中运行,这就是我得到的结果:
def possible(grid, y, x, n):
for i in range(0,9):
if grid[y][i] == n:
return False
if grid[i][x] == n:
return False
x0 = (x//3)*3
y0 = (y//3)*3
for i in range(0,3):
for j in range(0,3):
if grid[y0+i][x0+j] == n:
return False
return True
def solver(grid):
for y in range(9):
for x in range(9):
if grid[y][x] == 0:
for n in range(1,10):
if possible(grid, y, x, n):
grid[y][x] = n
solver(grid)
grid[y][x] = 0
return
print(np.matrix(grid))
这段代码工作正常。但是我想尝试让它在网络应用程序中工作,所以我将它翻译成 Javascript 像这样:
function possible(board, y, x, n) {
for(i = 0; i < 9; i++) {
if(board[y][i] === n) {
return false;
}
if(board[i][x] === n) {
return false;
}
}
y0 = Math.floor(y/3)*3;
x0 = Math.floor(x/3)*3;
for(i = 0; i < 3; i++) {
for(j = 0; j < 3; j++) {
if(board[i+y0][j+x0] === n) {
return false;
}
}
}
return true;
}
function solver(board) {
for(y = 0; y < 9; y++) {
for(x = 0; x < 9; x++) {
if(board[y][x] === 0) {
for(n = 1; n < 10; n++) {
if(possible(board, y, x, n)) {
board[y][x] = n;
solver(board);
board[y][x] = 0;
}
}
return;
}
}
}
console.log(board);
}
据我所知,这些功能完全相同,而且由于它在 Python 中有效,所以我不明白为什么它在 JavaScript 中不起作用。在 JS 中,它似乎从来没有达到 console.log(board) 线,所以我正在徘徊,如果我达到最大递归深度或类似的简单东西。
作为参考,这是在 Python 求解器中工作的网格:
grid = [
[5, 3, 0, 0, 7, 0, 0, 0, 0],
[6, 0, 0, 1, 9, 5, 0, 0, 0],
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1],
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0],
[0, 0, 0, 4, 1, 9, 0, 0, 5],
[0, 0, 0, 0, 8, 0, 0, 7, 9]
]
如果您在函数内使用 for 循环,var
将创建一个局部变量,“no var”将查找作用域链,直到找到该变量或到达全局作用域。
这意味着您需要在 for 循环内创建变量时声明 var
以避免一个循环与另一个循环混淆。阅读更多 here
因此您的代码应如下所示:
function possible(board, y, x, n) {
for (var i = 0; i < 9; i++) {
if (board[y][i] === n) {
return false;
}
if (board[i][x] === n) {
return false;
}
}
y0 = Math.floor(y / 3) * 3;
x0 = Math.floor(x / 3) * 3;
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
if (board[y0+i][x0+j] === n) {
return false;
}
}
}
return true;
}
function solver(board) {
for (var y = 0; y < 9; y++) {
for (var x = 0; x < 9; x++) {
if (board[y][x] === 0) {
for (var n = 1; n < 10; n++) {
if (possible(board, y, x, n)) {
board[y][x] = n;
solver(board);
board[y][x] = 0;
}
}
return
}
}
}
console.log(board);
}