Skip to content

Instantly share code, notes, and snippets.

@QuadFlask
Created March 28, 2016 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save QuadFlask/5f4627f3ca60fc4a3940 to your computer and use it in GitHub Desktop.
Save QuadFlask/5f4627f3ca60fc4a3940 to your computer and use it in GitHub Desktop.
[CodeWars] The observed PIN

넘버 키패드에서 가능한 조합 찾기

  • 후보 숫자들이 주어지고
  • 각 숫자의 상하좌우의 번호가 후보군이됨
  • 이 후보군들의 모든 조합들을 찾기

MySolution

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);
}

Best Practice (+9, clever+26)

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 를 쓰게 된다면 아래와 같은 헬이...

for hell

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;
}
@QuadFlask
Copy link
Author

자바에서처럼 인트스트림같은게 없어서 for(var i=0;i<10;i++) 과 같은 for문 반복을 할때 아래와 같이 하면 그나마 funcional한듯??

 Array.apply(null, Array(10)).map(function(){return 5})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment