넘버 키패드에서 가능한 조합 찾기
- 후보 숫자들이 주어지고
- 각 숫자의 상하좌우의 번호가 후보군이됨
- 이 후보군들의 모든 조합들을 찾기
var np = [['1','2','3'],['4','5','6'],['7','8','9'],[null,'0',null]];
function getPINs(observed) {
if(observed.length == 1) return getCloses(observed);
var numbers = observed.split('').map(s=>~~s).map(getCloses);
var com = (i, arr)=> {return arr.map(a=> ''+a+i)};
return getPINs(observed.substr(1)).map(i=>{return com(i, numbers[0])}).reduce((a,b)=>a.concat(b));
}
var pos = number=> {
for(var y=0;y<4;y++)
for(var x=0;x<3;x++) {
if(np[y][x] == number) return {x:x,y:y};
}
}
var atNp = p=> {
try {
return np[p.y][p.x];
} catch(e){ return undefined; }
}
var getCloses = n=> {
var p = pos(n);
return [
n,
atNp({x:p.x,y:p.y-1}),
atNp({x:p.x,y:p.y+1}),
atNp({x:p.x-1,y:p.y}),
atNp({x:p.x+1,y:p.y}),
].filter(i=>i!=undefined);
}
function getPINs(observed) {
var adjacent = [
/* 0 */ [0, 8],
/* 1 */ [1, 2, 4],
/* 2 */ [1, 2, 3, 5],
/* 3 */ [2, 3, 6],
/* 4 */ [1, 4, 5, 7],
/* 5 */ [2, 4, 5, 6, 8],
/* 6 */ [3, 5, 6, 9],
/* 7 */ [4, 7, 8],
/* 8 */ [5, 7, 8, 9, 0],
/* 9 */ [6, 8, 9]
];
return observed
.split('')
.map(function(d) { return adjacent[d|0]; })
.reduce(function(pa, da) {
return da.reduce(function(pv, d) {
return pv.concat(pa.map(function(p) {
return '' + p + d;
}));
}, []);
}, ['']);
}
가능하면 for
문이나 map
, 'filter,
reduce를 많이 쓸려고 노력했긴한데, 더 공부헤야할듯ㅋㅋ 이 문제는
for`문으로 풀기 겁나 빡심(만약 자리수가 unbounded 라면?ㅋㅋ) 그래서 재귀로 풀면 그나마 쉽게 풀리는데 재귀에 미숙해서 아직도 잘 못함...
만약 for
를 쓰게 된다면 아래와 같은 헬이...
function getPINs(observed) {
var obj = {
"0": ["0", "8"],
"1": ["1", "2", "4"],
"2": ["1", "2", "3", "5"],
"3": ["2", "3", "6"],
"4": ["1", "4", "5", "7"],
"5": ["2", "4", "5", "6", "8"],
"6": ["3", "5", "6", "9"],
"7": ["4", "7", "8"],
"8": ["0","5", "7", "8", "9"],
"9": ["6", "8", "9"]
};
observed=observed.split('');
var varMass = [];
observed.forEach(function(elem){
varMass.push(obj[elem]);
});
var variants=[];
varMass[0].forEach(function (el0){
if(varMass[1]!==undefined) {
varMass[1].forEach(function (el1) {
if (varMass[2] !== undefined) {
varMass[2].forEach(function (el2) {
if(varMass[3]!==undefined){
varMass[3].forEach(function(el3){
if(varMass[4]!==undefined){
varMass[4].forEach(function(el4){
if(varMass[5]!==undefined){
varMass[5].forEach(function(el5){
if(varMass[6]!==undefined){
varMass[6].forEach(function(el6){
if(varMass[7]!==undefined){
varMass[7].forEach(function(el7){
variants.push(el0 + el1 + el2 + el3 + el4 + el5 + el6 +el7);
})
}else {
variants.push(el0 + el1 + el2 + el3 + el4 + el5 + el6);
}
})
}else {
variants.push(el0 + el1 + el2 + el3 + el4 + el5);
}
})
} else {
variants.push(el0 + el1 + el2 + el3+el4);
}
});
}else {
variants.push(el0 + el1 + el2 + el3);
}
});
}else {
variants.push(el0+el1+el2);
}
});
}else {
variants.push(el0+el1);
}
});
}else {
variants.push(el0)
}
});
return variants;
}
자바에서처럼 인트스트림같은게 없어서
for(var i=0;i<10;i++)
과 같은for
문 반복을 할때 아래와 같이 하면 그나마 funcional한듯??