You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数独校验器Bug排查:无效返回False正确但有效不返回True

数独校验器有效时无法返回true的问题分析

我正在完成编程入门课程的期末项目,数独校验器存在问题:无效数独能正确返回false,但有效数独却无法返回true,已经花了一小时排查仍没头绪,求分析。

以下是相关代码:

//puzzle
let puzzle = [[ 8,9,5,   7,4,2,   1,3,6 ],
              [ 2,7,1,   9,6,3,   4,8,5 ],
              [ 4,6,3,   5,8,1,   7,9,2 ],

              [ 9,3,4,   6,1,7,   2,5,8 ],
              [ 5,1,7,   2,3,8,   9,6,4 ],
              [ 6,8,2,   4,5,9,   3,7,1 ],

              [ 1,5,9,   8,7,4,   6,2,3 ],
              [ 7,4,6,   3,2,5,   8,1,9 ],
              [ 3,2,8,   1,9,6,   5,4,7 ]];


//puzzle 2
let puzzleTwo = [[ 8,9,5,7,4,2,1,3,6 ],
                [ 8,7,1,9,6,3,4,8,5 ],
                [ 4,6,3,5,8,1,7,9,2 ],
                [ 9,3,4,6,1,7,2,5,8 ],
                [ 5,1,7,2,3,8,9,6,4 ],
                [ 6,8,2,4,5,9,3,7,1 ],
                [ 1,5,9,8,7,4,6,2,3 ],
                [ 7,4,6,3,2,5,8,1,9 ],
                [ 3,2,8,1,9,6,5,4,7 ]];

//DO NOT EDIT ABOVE

function getRow(puzzle, row) {
    // YOUR CODE
    return puzzle[row];                              
}

function getColumn(puzzle, col) {
    // YOUR CODE
    let column = [];
    for (let i = 0; i < puzzle.length; i++) {
        column.push(puzzle[i][col]);
    }
    return column;
}

function getSection(puzzle, x, y) {
    // YOUR CODE
    let numSubgrid = [];
    x *= 3;
    y *= 3;
    for (let i = y; i < y + 3; i++) {
        for (let j = x; j < x + 3; j++) {
            numSubgrid.push(puzzle[i][j])
        }
    }
    return numSubgrid;
}

function includes1To9(arr) {
    // YOUR CODE
    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length; j++) {
            if (i !== j && arr[i] === arr[j]) {
                return false;
            } 
        }
    }
    return true;
}

function sudokuIsValid(puzzle) {
    // YOUR CODE
    if (includes1To9(getRow) || includes1To9(getColumn) || includes1To9(getSection) !== true) {
        return false;
    }
    return true;
}

问题根源分析

1. sudokuIsValid函数逻辑完全错误

  • 代码直接将getRow、getColumn、getSection函数本身传入includes1To9,而非调用这些函数获取数独的行、列、区块数据。函数作为参数传入时,includes1To9遍历的是函数对象的属性,完全不是预期的数独数字数组。
  • 判断逻辑颠倒:数独要求所有行、所有列、所有区块都必须符合规则,只要有一个不符合则无效;当前代码的逻辑是只要其中一个函数(作为参数)满足includes1To9就返回false,完全不符合校验要求。

2. includes1To9函数存在缺陷

  • 该函数仅检查数组内是否有重复值,但未验证数组是否包含1-9的所有数字。例如数组[1,2,3,4,5,6,7,8,0]没有重复值,但包含非法数字0,这个函数会错误返回true,不符合数独规则。

修正后的代码

修正includes1To9函数

function includes1To9(arr) {
    // 数独的行/列/区块必须是9个元素
    if (arr.length !== 9) return false;
    // 用Set去重,同时检查是否包含1-9所有数字
    const numSet = new Set(arr);
    for (let num = 1; num <= 9; num++) {
        if (!numSet.has(num)) {
            return false;
        }
    }
    return true;
}

修正sudokuIsValid函数

function sudokuIsValid(puzzle) {
    // 校验所有行
    for (let row = 0; row < 9; row++) {
        if (!includes1To9(getRow(puzzle, row))) {
            return false;
        }
    }
    // 校验所有列
    for (let col = 0; col < 9; col++) {
        if (!includes1To9(getColumn(puzzle, col))) {
            return false;
        }
    }
    // 校验所有3x3区块(x和y取值0-2,对应3x3区块的索引)
    for (let x = 0; x < 3; x++) {
        for (let y = 0; y < 3; y++) {
            if (!includes1To9(getSection(puzzle, x, y))) {
                return false;
            }
        }
    }
    // 所有校验通过,返回true
    return true;
}

验证说明

  • 修正后的includes1To9会同时检查数组长度、是否包含1-9所有数字(自动排除重复,因为Set会去重,若有重复则Set大小小于9,循环检查1-9时会发现缺失)。
  • sudokuIsValid会遍历每一行、每一列、每一个3x3区块,逐一校验,只要有一个不符合规则就返回false,全部通过则返回true。

内容的提问来源于stack exchange,提问作者Cluff3rs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 04:18:16