【CodeWars】Sudoku Solution Validator

题目链接:https://www.codewars.com/kata/529bf0e9bdf7657179000008/train/javascript
要求:校验一个数独结果是否正确。
思路:遍历二维数组中的9个子数组,遇到以下两种情况时return false:
(1)不是1-9以内的数字(有0);
(2)数组内有重复的数字(也就是去重之后的数组length!==9)
遍历每一行比较简单,遍历每一列就是先翻转矩阵,然后按照遍历行的方式再遍历一次。
数独还要求每个九宫格不能重复数字,所以还要把每个九宫格的九个数放到一个数组里组成一个二维数组,随后就可以按照同样的方法再次遍历。

较多的代码花在了如何取出每个九宫格的数据上:

//board形参是原二维数组
const getReversed2 = (board) => {
  let lStart = 0;   //行基准
  let rStart = 0;   //列基准
  let line = 0;
  let j = 0;
  const res = [];
  let temp = [];
  for (lStart = 0; lStart <= 6; lStart = lStart + 3) {
    for (rStart = 0; rStart <= 6; rStart = rStart + 3) {
      temp = [];
      for (line = lStart; line < lStart + 3; line++) {
        for (j = rStart; j < rStart + 3; j++) {
          //取出当前行的三个数据之后、跳转到下一行
          temp.push(board[line][j]);
        }
      }
      res.push(temp);
    }
  }
  return res;
};

整个题目的答案:

const LENGTH = 9;
const resolveFunc = (board) => {
  let res = true;
  board.forEach((arr) => {
    if (arr.includes(0)) {
      res = false;
    }
    // 去重以后的数组长度
    if (Array.from(new Set(arr)).length !== LENGTH) {
      res = false;
    }
  });
  return res;
};

const getReversed2 = (board) => {
  let lStart = 0;
  let rStart = 0;
  let line = 0;
  let j = 0;
  const res = [];
  let temp = [];
  for (lStart = 0; lStart <= 6; lStart = lStart + 3) {
    for (rStart = 0; rStart <= 6; rStart = rStart + 3) {
      temp = [];
      for (line = lStart; line < lStart + 3; line++) {
        for (j = rStart; j < rStart + 3; j++) {
          temp.push(board[line][j]);
        }
      }
      res.push(temp);
    }
  }
  return res;
};

const validSolution = (board) => {
  console.log(resolveFunc(board));
  if (!resolveFunc(board)) {
    return false;
  }

  let i = 0;
  const reversed = [];
  for (i = 0; i < LENGTH; i++) {
    const temp = [];
    board.forEach((arr) => {
      temp.push(arr[i]);
    });
    reversed.push(temp);
  }
  if (!resolveFunc(reversed)) {
    return false;
  }

  const reversed2 = getReversed2(board);
  if (!resolveFunc(reversed2)) {
    return false;
  }

  return true;
};

其实我的思路是很简单的,其他答案的思路更好,代码量少很多,比如在取每个九宫格中的数据时使用的方法就比较复杂

function validSolution(board){
  var validSet = s => s.size == 9 && !s.has(0);
  var rowSet = i => board[i].reduce((s,v) => s.add(v), new Set());
  var columnSet = i => board.reduce((s,v) => s.add(v[i]), new Set());
  //r=>000/333/666; c=>036/036/036;
  //一个boxSet就是一个九宫格
  var boxSet = ([r,c]) => board.slice(r,r+3).reduce((s,v) => v.slice(c,c+3).reduce((s,v) => s.add(v), s), new Set());
  var boxCorner = i => [Math.floor(i / 3) * 3,(i % 3) * 3];
  for (var i = 0; i < 9; i++)
    if ( !validSet(rowSet(i)) || !validSet(columnSet(i)) || !validSet(boxSet(boxCorner(i))) )
      return false;
  return true;
}
posted @ 2021-07-05 18:55  bcj7wi3kd5h1wd6  阅读(94)  评论(0编辑  收藏  举报