Given a Sudoku data structure with size NxN, N > 0 and √N == integer
, write a method to validate if it has been filled out correctly.
The data structure is a multi-dimensional Array, i.e:
[
[7,8,4, 1,5,9, 3,2,6],
[5,3,9, 6,7,2, 8,4,1],
[6,1,2, 4,3,8, 7,5,9],
[9,2,8, 7,1,5, 4,6,3],
[3,5,7, 8,4,6, 1,9,2],
[4,6,1, 9,2,3, 5,8,7],
[8,7,6, 3,9,4, 2,1,5],
[2,4,3, 5,6,1, 9,7,8],
[1,9,5, 2,8,7, 6,3,4]
]
Rules for validation
NxN
where N > 0
and √N == integer
1..N (N included)
1..N (N included)
3x3
in example above) may also only contain integers: 1..N (N included)
var Sudoku = function(data)
{
let sortedArray = [];
const N = data.length;
for(l=1;l<N+1;l++) {
sortedArray.push(l);
}
function notNumber(array) {
for (k=0;k<array.length;k++) {
if(typeof(array[k]) != "number") {
return true;
}
}
return false;
}
function checkDimension(data) {
for(i of data) {
if(i.length != N) {
return false;
} else if(i == 0) {
return false;
} else if(notNumber(i)) {
return false;
}
}
return true;
}
function ifIncludes(a, b) {
return a.every(element=>b.includes(element)) && b.every(element=>a.includes(element)) ;
}
function checkRow(data) {
for(i of data) {
if(!ifIncludes(i,sortedArray)) {
return false;
}
}
return true;
}
let columnArray = [];
function checkColumn(data) {
for(i of data) {
for(j=0;j<i.length;j++) {
if(!columnArray[j]) {
columnArray[j] = [];
columnArray[j].push(i[j]);
} else {
columnArray[j].push(i[j]);
}
}
}
for(i of columnArray) {
if(!ifIncludes(i,sortedArray)) {
return false;
}
}
return true;
}
let boxArray = [];
function checkBox(data) {
const n = Math.sqrt(N);
if(!Number.isInteger(n)) {
return false;
}
for (let m=0;m<N;m++) {
let q = parseInt(m / n) * n;
let d = m % n * n;
if(!boxArray[m]) {
boxArray[m] = [];
}
for(j=q;j<q+n;j++) {
for(k=d;k<d+n;k++) {
boxArray[m].push(data[j][k]);
}
}
}
for(i of boxArray) {
if(!ifIncludes(i,sortedArray)) {
return false;
}
}
return true;
}
return {
isValid: function() {
return (checkDimension(data) && checkRow(data) && checkColumn(data) && checkBox(data));
}
};
};
길이가 N-1인 배열이 1~N을 모두 포함하는지 알아내는법
function checkArray(array){
const copy = array.slice(0); // 1
copy.sort(function(a,b){
return a - b;
}); // 2
return copy.every(function(val,index){
return index + 1 === val;
}); // 3
}
array.slice(begin, end)
array의 begin부터 end까지에 대한 깊은 복사 같은 얕은 복사를 새로운 배열로 반환한다. 깊은 복사처럼 보이지만, 중첩된 구조를 변경하게 되면 원본도 함께 변한다.
const arr = [1, 2, [3, 4]];
const copied = arr.slice();
copied.push(6);
console.log(copied == array); // false (깊은 복사됨)
copied[2].push(5);
console.log(copied == array); // false (실제로는 얕은 복사임)
end
생략되면 자동으로 배열의 끝까지 추출한다.
이러한 이유로 array.slice(0)을 하게 되면 array의 처음부터 끝까지 얕은 복사를 하게 된다.
번외; 깊은 복사는?
추후 공부가 필요함!
array.sort(compareFunction)
배열의 요소를 적절한 위치에 정렬한 후 배열을 반환한다.
compareFunction
compareFunction이 주어지지 않았을 때는 default값으로 유니코드 코드 포인트 값을 따른다.
배열을 오름차순으로 정렬하려면 다음과 같이 작성한다.
function compareNumber(a,b) {
return a-b;
}
array.every(callbackFn)
callbackFn이 배열 안의 모든 요소에 대하여 true이면 true를 반환한다.
callbackFn(element, index, array)
index와 array는 optional이다.