gpt4 book ai didi

java - 数独生成器的递归求解

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:23:37 25 4
gpt4 key购买 nike

我正在尝试编写一种算法,以使用 Java 或 Javascript 创建合法的数独板。两者都不起作用,我不完全确定为什么。

本质上,这两个程序中的问题是 x 或 y 的增量超过了应有的增量(跳过正方形)。我一辈子都弄不明白这是怎么回事。如果需要,我可以提供完成 JS 解决方案的 HTML。

我最好的猜测是它与我如何使用递归创建堆栈有关,但据我所知,它应该有效。在我的旧代码中有一个不正确的 for 循环,我知道这一点。我粘贴了一个旧版本,现在已修复。

java :

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;
}

Javascript:

//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;

最佳答案

在 Java 代码中:我会将其翻译成伪代码:

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

但是,如果您不能在其中输入任何数字,因为它最终是非法的(也就是您不能在特定方 block 中插入任何数字的板)怎么办?

你没有解决这个问题。您需要做的是通过回溯实现它:

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)

关于java - 数独生成器的递归求解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9959172/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com