在JavaScript中生成随机的Sudoku难题导致无法解决的板
我试图产生可以解决的随机Sudoku难题,但遇到了麻烦。我能够创建一个带有值的9x9二维数组,但是通常,这些值已经在自己的行中重复。我如何防止这种情况发生?以下是我的功能,该功能应该返回带有空位的Sudoku板。
function pattern (r, c, base, side) { return (base * (r % base) + Math.floor(r / base) + c) % side; }
function shuffle (s) { return s.sort(function () { return Math.random() - 0.5; }); }
function getGrid () {
var X = 0;
var base = 3;
var side = base * base;
var rows = [], columns = [], numbers = [], b = [], newB = [];
for (var x = 0; x < base; x++) {
for (var y = 0; y < base; y++) {
rows.push(X * base + y);
columns.push(x * base + y);
}
}
rows = shuffle(rows);
columns = shuffle(columns);
for (var n = 1; n < base * base + 1; n++) { numbers.push(n); }
numbers = shuffle(numbers);
for (var r = 0; r < rows.length; r++) {
for (var c = 0; c < columns.length; c++) {
b.push(numbers[pattern(rows[r], columns[c], base, side)]);
}
}
while (b.length) { newB.push(b.splice(0, 9)); }
console.log(newB); // before removing some items, complete puzzle
var squares = side * side;
var emptySpots = Math.floor((squares * 3) / 4);
for (var cell = 0; cell < squares; cell++) {
if (Math.random() < 0.4) { newB[Math.floor(cell / side)][cell % side] = X; }
}
console.log(newB); // after removing some items, unsolved puzzle
return newB;
}
这是我从此功能中收到的输出的示例:
0: (9) [6, 3, 7, 0, 1, 5, 2, 8, 9]
1: (9) [7, 1, 2, 0, 0, 0, 6, 4, 8]
2: (9) [6, 3, 7, 4, 1, 0, 2, 8, 9]
3: (9) [6, 0, 0, 4, 1, 5, 2, 8, 0]
4: (9) [7, 0, 0, 0, 0, 3, 6, 0, 8]
5: (9) [0, 5, 0, 8, 3, 0, 0, 0, 4]
6: (9) [7, 1, 0, 0, 0, 0, 6, 4, 8]
7: (9) [0, 0, 6, 0, 0, 0, 0, 9, 4]
8: (9) [0, 5, 6, 8, 3, 0, 7, 9, 4]
这不是可解决的sudoku板,因为在同一行/列/方形中重复了值。有人有想法吗?
getGrid();
function pattern (r, c, base, side) { return (base * (r % base) + Math.floor(r / base) + c) % side; }
function shuffle (s) { return s.sort(function () { return Math.random() - 0.5; }); }
function getGrid () {
var X = 0;
var base = 3;
var side = base * base;
var rows = [], columns = [], numbers = [], b = [], newB = [];
for (var x = 0; x < base; x++) {
for (var y = 0; y < base; y++) {
rows.push(X * base + y);
columns.push(x * base + y);
}
}
rows = shuffle(rows);
columns = shuffle(columns);
for (var n = 1; n < base * base + 1; n++) { numbers.push(n); }
numbers = shuffle(numbers);
for (var r = 0; r < rows.length; r++) {
for (var c = 0; c < columns.length; c++) {
b.push(numbers[pattern(rows[r], columns[c], base, side)]);
}
}
while (b.length) { newB.push(b.splice(0, 9)); }
console.log(newB); // before removing some items, complete puzzle
var squares = side * side;
var emptySpots = Math.floor((squares * 3) / 4);
for (var cell = 0; cell < squares; cell++) {
if (Math.random() < 0.4) { newB[Math.floor(cell / side)][cell % side] = X; }
}
console.log(newB); // after removing some items, unsolved puzzle
return newB;
}
编辑:我在Python中制作了相同的程序,该程序正常工作,我试图在JavaScript中重写相同的功能,但结果是不同的。这是Python中的工作版本:
def get_board():
global _board
global empty
base = 3
side = base * base
def pattern(r, c): return (base * (r % base) + r // base + c) % side
def shuffle(s): return sample(s, len(s))
rows = [g * base + row for g in shuffle(range(base)) for row in shuffle(range(base))]
columns = [g * base + column for g in shuffle(range(base)) for column in shuffle(range(base))]
numbers = shuffle(range(1, base * base + 1))
_board = [[numbers[pattern(r, c)] for c in columns] for r in rows]
squares = side * side
empties = squares * 3 // 4
for p in sample(range(squares), empties): _board[p // side][p % side] = empty
有人可以告诉我算法有何不同?
im trying to generate random sudoku puzzles that can be solved, but am having trouble. i am able to create a 9x9 two-dimensional array with values, but oftentimes, the values have repeated in their own row. how can I prevent this from happening? below is my function which should return a sudoku board with emptied spots to solve.
function pattern (r, c, base, side) { return (base * (r % base) + Math.floor(r / base) + c) % side; }
function shuffle (s) { return s.sort(function () { return Math.random() - 0.5; }); }
function getGrid () {
var X = 0;
var base = 3;
var side = base * base;
var rows = [], columns = [], numbers = [], b = [], newB = [];
for (var x = 0; x < base; x++) {
for (var y = 0; y < base; y++) {
rows.push(X * base + y);
columns.push(x * base + y);
}
}
rows = shuffle(rows);
columns = shuffle(columns);
for (var n = 1; n < base * base + 1; n++) { numbers.push(n); }
numbers = shuffle(numbers);
for (var r = 0; r < rows.length; r++) {
for (var c = 0; c < columns.length; c++) {
b.push(numbers[pattern(rows[r], columns[c], base, side)]);
}
}
while (b.length) { newB.push(b.splice(0, 9)); }
console.log(newB); // before removing some items, complete puzzle
var squares = side * side;
var emptySpots = Math.floor((squares * 3) / 4);
for (var cell = 0; cell < squares; cell++) {
if (Math.random() < 0.4) { newB[Math.floor(cell / side)][cell % side] = X; }
}
console.log(newB); // after removing some items, unsolved puzzle
return newB;
}
here is an example of an output which i have recieved from this function:
0: (9) [6, 3, 7, 0, 1, 5, 2, 8, 9]
1: (9) [7, 1, 2, 0, 0, 0, 6, 4, 8]
2: (9) [6, 3, 7, 4, 1, 0, 2, 8, 9]
3: (9) [6, 0, 0, 4, 1, 5, 2, 8, 0]
4: (9) [7, 0, 0, 0, 0, 3, 6, 0, 8]
5: (9) [0, 5, 0, 8, 3, 0, 0, 0, 4]
6: (9) [7, 1, 0, 0, 0, 0, 6, 4, 8]
7: (9) [0, 0, 6, 0, 0, 0, 0, 9, 4]
8: (9) [0, 5, 6, 8, 3, 0, 7, 9, 4]
this isn't a solvable sudoku board, as there are values repeated in the same row/column/square. does anyone have any ideas?
getGrid();
function pattern (r, c, base, side) { return (base * (r % base) + Math.floor(r / base) + c) % side; }
function shuffle (s) { return s.sort(function () { return Math.random() - 0.5; }); }
function getGrid () {
var X = 0;
var base = 3;
var side = base * base;
var rows = [], columns = [], numbers = [], b = [], newB = [];
for (var x = 0; x < base; x++) {
for (var y = 0; y < base; y++) {
rows.push(X * base + y);
columns.push(x * base + y);
}
}
rows = shuffle(rows);
columns = shuffle(columns);
for (var n = 1; n < base * base + 1; n++) { numbers.push(n); }
numbers = shuffle(numbers);
for (var r = 0; r < rows.length; r++) {
for (var c = 0; c < columns.length; c++) {
b.push(numbers[pattern(rows[r], columns[c], base, side)]);
}
}
while (b.length) { newB.push(b.splice(0, 9)); }
console.log(newB); // before removing some items, complete puzzle
var squares = side * side;
var emptySpots = Math.floor((squares * 3) / 4);
for (var cell = 0; cell < squares; cell++) {
if (Math.random() < 0.4) { newB[Math.floor(cell / side)][cell % side] = X; }
}
console.log(newB); // after removing some items, unsolved puzzle
return newB;
}
EDIT: i made the same program in python which worked perfectly, and i attempted to rewrite the same function in javascript, but the results are different. here is the working version in python:
def get_board():
global _board
global empty
base = 3
side = base * base
def pattern(r, c): return (base * (r % base) + r // base + c) % side
def shuffle(s): return sample(s, len(s))
rows = [g * base + row for g in shuffle(range(base)) for row in shuffle(range(base))]
columns = [g * base + column for g in shuffle(range(base)) for column in shuffle(range(base))]
numbers = shuffle(range(1, base * base + 1))
_board = [[numbers[pattern(r, c)] for c in columns] for r in rows]
squares = side * side
empties = squares * 3 // 4
for p in sample(range(squares), empties): _board[p // side][p % side] = empty
could someone tell me how the algorithms differ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我只是为了娱乐而制作了一个(在Python算法之前,因为我不知道限制),这对想到的第一个算法不优化。
PS:〜2H:10分钟
编辑1:重新检查Sudoku规则
编辑2:Hack&amp;漏洞
I made one just for fun (before the Python algorithm, because I didn't know the restriction), unoptimised with the first algorithm that came to mind.
PS: ~ 2h:10min
EDIT 1: Recheck Sudoku rules
EDIT 2: Hack & bug
似乎这个答案可以解决您的问题
https://stackoverflow.com/a/76596381/2674707
我分享我的想法
构建完整的sudoku
您可以在完整空白上生成一个随机1-9的地方(例如中间中心)矩阵,看起来像这样:
因此您可以使用 backtrace 求解并制作完整的sudoku
随机“挖掘孔”,在每个“挖掘孔”之后,您需要验证此难题是
基于完整的Sudoku,您可以清除随机位置的数量,即我称其为“挖洞”,在每个挖洞之后,您需要验证拼图并确保是一号解决方案,直到所有挖洞都完成
“ DIG HOLD”计数是
您的项目中的Sudoku拼图困难,四级难度:easy(40) /媒介( 45) / HARD(50) /专家(56)
参考文献
>用不同的语言
seem this answer can solve your question
https://stackoverflow.com/a/76596381/2674707
that is I did and seem work very well , so I'am share my idea
build complete Sudoku
you can generate one place (like middle center one) with random 1-9 on complete blank matrix, look like this :
so you can use backtrace solve and make complete sudoku
random "dig hole" , after each "dig hole" you need verify this puzzle is one-solution
based on the complete sudoku , you can clear number of random position at it , that I'am call it "dig hole" , after each dig hole , you need to verify the puzzle and make sure is one-solution, until all dig hole done
the "dig hold" count is your sudoku puzzle difficulty
in my project , four level difficulty : easy(40) / medium(45) / hard(50) / expert(56)
references
I'am write sudoku solver and generator lib with different languages, maybe you can refer to it: