在尝试用 Javascript 实现数独求解器时,我的逻辑哪里出了问题?

Posted

技术标签:

【中文标题】在尝试用 Javascript 实现数独求解器时,我的逻辑哪里出了问题?【英文标题】:Where has my logic gone wrong in my attempt to implement a sudoku solver in Javascript? 【发布时间】:2020-08-26 02:16:38 【问题描述】:

const N = 4;
const fourbyfour = [
  [1, 0, 0, 4],
  [3, 4, 1, 2],
  [2, 1, 4, 3],
  [4, 3, 2, 1],
];

function solve(board) 
  for (let i = 0; i < N; i++) 
    for (let j = 0; j < N; j++) 
      if (board[i][j] === 0) 
        for (let k = 1; k < N + 1; k++) 
          board[i][j] = k;
          if (isValidBoard(board)) 
            if (isSolved(board)) return board;
            else solve(board);
          
        
      
    
  
  return;


function isSolved(board) 
  let cells = [];
  for (let row of board) 
    cells.push(...row);
  
  return !cells.includes(0);


function isValidBoard(board) 
  // Check rows are valid
  for (let i = 0; i < N; i++) 
    const row = board[i].filter((cell) => cell !== 0);
    if (new Set(row).size !== row.length) 
      return false;
    
  

  // Check columns are valid
  for (let i = 0; i < N; i++) 
    let column = [];
    for (let j = 0; j < N; j++) 
      if (board[j][i] !== 0) column.push(board[j][i]);
    
    if (new Set(column).size !== column.length) 
      return false;
    
  

  const root = Math.sqrt(N);
  // Check each grid
  for (let i = 0; i < N; i += root) 
    for (let j = 0; j < N; j += root) 
      const square = [];
      for (let k = i; k < i + root; k++) 
        for (let l = j; l < j + root; l++) 
          if (board[k][l] !== 0) 
            square.push(board[k][l]);
          
        
      
      if (new Set(square).size !== square.length) 
        return false;
      
    
  
  return true;

console.table(solve(fourbyfour));

solve() 继续返回未定义。 我相当确定问题出在求解函数中,与 isSolved() 和 isValidBoard() 无关。解决函数正在获取正确的电路板,如果我控制台记录电路板而不是返回它,则会打印正确的电路板,但由于某种原因它没有被返回。

【问题讨论】:

我觉得添加几个大括号可以帮助您解决问题。 你不应该在这里返回值,即else solve(board);应该是else return solve(board); 吗? 谢谢!你是对的。 @user2740650 【参考方案1】:

您永远不会返回递归的值。您需要从输入solve次返回。

另外,console.table 不适合在 sn-p 中工作

const N = 4;
const fourbyfour = [
  [1, 0, 0, 4],
  [3, 4, 1, 2],
  [2, 1, 4, 3],
  [4, 3, 2, 1],
];

function solve(board) 
  for (let i = 0; i < N; i++) 
    for (let j = 0; j < N; j++) 
      if (board[i][j] === 0) 
        for (let k = 1; k < N + 1; k++) 
          board[i][j] = k;
          if (isValidBoard(board)) 
            if (isSolved(board)) 
              return board;
             else 
              return solve(board);
            
          
        
      
    
  
  return 'test';


function isSolved(board) 
  let cells = [];
  for (let row of board) 
    cells.push(...row);
  
  return !cells.includes(0);


function isValidBoard(board) 
  // Check rows are valid
  for (let i = 0; i < N; i++) 
    const row = board[i].filter((cell) => cell !== 0);
    if (new Set(row).size !== row.length) 
      return false;
    
  

  // Check columns are valid
  for (let i = 0; i < N; i++) 
    let column = [];
    for (let j = 0; j < N; j++) 
      if (board[j][i] !== 0) column.push(board[j][i]);
    
    if (new Set(column).size !== column.length) 
      return false;
    
  

  const root = Math.sqrt(N);
  // Check each grid
  for (let i = 0; i < N; i += root) 
    for (let j = 0; j < N; j += root) 
      const square = [];
      for (let k = i; k < i + root; k++) 
        for (let l = j; l < j + root; l++) 
          if (board[k][l] !== 0) 
            square.push(board[k][l]);
          
        
      
      if (new Set(square).size !== square.length) 
        return false;
      
    
  
  return true;

console.log(solve(fourbyfour));

【讨论】:

以上是关于在尝试用 Javascript 实现数独求解器时,我的逻辑哪里出了问题?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 数独求解器在某些板上陷入无限循环/不适用于所有板

无法回溯以使用递归 javascript 数独求解器

为啥这个数独求解器返回相同的板而不解决任何问题?

求解数独的所有解法,java编程实现

数独游戏求解程序

Java问题中的蛮力数独求解器算法