The observed PIN

SungJunEun·2021년 11월 12일
0

Codewars 문제풀이

목록 보기
14/26
post-thumbnail

Description:

Alright, detective, one of our colleagues successfully observed our target person, Robby the robber. We followed him to a secret warehouse, where we assume to find all the stolen stuff. The door to this warehouse is secured by an electronic combination lock. Unfortunately our spy isn't sure about the PIN he saw, when Robby entered it.

The keypad has the following layout:

┌───┬───┬───┐
│ 1 │ 2 │ 3 │
├───┼───┼───┤
│ 4 │ 5 │ 6 │
├───┼───┼───┤
│ 7 │ 8 │ 9 │
└───┼───┼───┘
    │ 0 │
    └───┘

He noted the PIN 1357, but he also said, it is possible that each of the digits he saw could actually be another adjacent digit (horizontally or vertically, but not diagonally). E.g. instead of the 1 it could also be the 2 or 4. And instead of the 5 it could also be the 246 or 8.

He also mentioned, he knows this kind of locks. You can enter an unlimited amount of wrong PINs, they never finally lock the system or sound the alarm. That's why we can try out all possible (*) variations.

  • possible in sense of: the observed PIN itself and all variations considering the adjacent digits

Can you help us to find all those variations? It would be nice to have a function, that returns an array (or a list in Java/Kotlin and C#) of all variations for an observed PIN with a length of 1 to 8 digits. We could name the function getPINs (get_pins in python, GetPINs in C#). But please note that all PINs, the observed one and also the results, must be strings, because of potentially leading '0's. We already prepared some test cases for you.

Detective, we are counting on you!

My solution:

풀지 못하여씁니다...

Best solutions:

function getPINs(observed) {
  return observed.split('')
  .map( t => ({
    '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' ]
  }[t]))
  .reduce((pre, cur)=> [].concat.apply([], pre.map(t => cur.map(g => t + g))));
}

코드 분해하기

  1. 배열의 요소를 새로 만든 오브젝트의 인덱스로 사용해서 새로운 배열을 만든다.
    observed.split('')
      .map( t => ({
        '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' ]
      }[t]);
ex) [1,2,3] → [ [ '1', '2', '4' ], [ '1', '2', '3', '5' ],  [ '2', '3', '6' ] ]
  1. reduce 메서드의 첫번째 iteration에서 pre = [ '1', '2', '4' ], cur = [ '1', '2', '3', '5' ]이다. 이 때,
    pre.map(t => cur.map(g => t + g));
   1. t = '1'일 때,
    
      cur.map(g => '1' + g);
     [ '11', '12', '13', '14', '15' ]을 반환한다.
    
    2. t가 '2'와 '4'일 때에도 동일하게 해보면

   전체 map 메서드는 [ ["11", "12", "13", "15"], ["21", "22", "23", "25"], ["41", "42", "43", "45"] ]의 새로운 배열을 만든다.
  1. concat.apply 메서드에 대하여 알아보자.
  • array.concat

    인자로 주어진 배열이나 값을 기존 배열에 합쳐서 새 배열을 반환한다.

    하지만, 여기서 핵심은 배열을 합친다면, 배열을 한번 제거해서 합친다. 예제로 알아보자.

        [1,2,3].concat(4,5,6); // [1,2,3,4,5,6]
        [1,2,3].concat([4,5,6); // [1,2,3,4,5,6]
        [1,2,3].concat([[4]]); // [1,2,3,[4]]
        [1,2,3].concat([4],5,6,[[7]]); // [1,2,3,4,5,6,7]
  • function.apply(thisArg, [argsArray])

    • thisArg

      첫번째 인자는 함수를 호출하는데 제공되는 this값이 된다.

    • argrsArray

      함수가 호출되어야 하는 인수

    이제 2 메서드를 합쳐보자.

    // when pre는 [ '1', '2', '4' ], cur = [ '1', '2', '3', '5' ]
    [].concat.apply([], pre.map(t => cur.map(g => t + g)));
    // equals to 
    [].concat.apply([], [["11", "12", "13", "15"], ["21", "22", "23", "25"], ["41", "42", "43", "45"]]);

여기서 apply 메서드의 2번째 인자에 대해서 조금 더 살펴보면, 함수가 호출되어야 하는 인수가 [], 배열로 묶여 있다. 그리하여

    [].concat.apply([], [["11", "12", "13", "15"], ["21", "22", "23", "25"], ["41", "42", "43", "45"]]);
    // equals to 
    [].concat(["11", "12", "13", "15"],["21", "22", "23", "25"],["41", "42", "43", "45"]);

여기서 concat 메서드에 의하여서 최종 값은 ["11", "12", "13", "15", "21", "22", "23", "25", "41", "42", "43", "45"]이 된다.


이후 reduce 함수에 의하여서 pre = ["11", "12", "13", "15", "21", "22", "23", "25", "41", "42", "43", "45"], cur = [ '2', '3', '6' ]이 되고, 위 과정을 반복한다.

profile
블록체인 개발자(진)

0개의 댓글