题目链接: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;
}