ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로그래머스 - [카카오 인턴] 키패드 누르기
    Algorithm 2023. 5. 6. 00:21

     

    문제

     

    풀이

    카카오 인턴쉽 문제답게 상당히 어려운 문제였다. 풀고자 했던 의도는 키패드를 먼저 2차원 평면 좌표로 구현하기 위해 2차원 배열로 좌표들을 지정해 주었고, 현재 왼손 시작 좌표, 오른손 시작 좌표를 지정해 준 다음 numbers 배열들을 좌표에 매칭시켰다.

    키패드를 좌표화 한 후 왼손위치와 오른손위치 표시

    먼저 1번, 4번, 7번에 해당되는 (1, 0), (2, 0), (3, 0)일 때 "L"을 추가하고

    3번, 6번, 9번에 해당되는 (1, 2), (2, 2), (3, 2)일 때 "R"을 추가시킨다.

    남은 0번, 2번, 5번, 8번을 처리할 때가 관건인데 이는 예시를 통해 이해해보자

     

    왼손 위치가 키패드4번, 오른손 위치가 키패드9번에 있을 때 다음으로 5번 키를 눌러야 하는 상황

    유클리드 거리(Euclidean Distance)

    9번에서 5번을 가기위해 걸리는 거리는 (1,2)와 (2,1)사이의 거리를 구하기 위해서 유클리드 거리를 계산하기 위해

    Math.sqrt(Math.pow(1-2, 2) + Math.pow(2-1, 2)) 의 연산을 했더니 계속 풀리지 않아 의문을 가졌다.

    그리고 문제의 예제 설명을 자세히 보니 9번에서 5번으로 가는 거리가 루트2가 아닌 2라고 표기된 것을 발견했다

    그제서야 문제 조건에서 손의 위치는 상하좌우로만 이동할 수 있다는 것을 발견했다.... (문제 조건을 확실하게 읽자ㅠ)

    즉, 피타고라스 공식을 사용하는 유클리드 거리가 아닌 맨하탄 거리를 이용해서 구해야 한다는 것이었다.

    맨하탄 거리(Manhattan Distance)

    따라서, x좌표간의 차이 + y좌표간의 차이를 구하면 되기에 Math.abs((1-2) + (2-1)) 로 구현해 주니 해결되었다.

    그리고 왼손위치에서 계산한 맨하탄 거리와 오른손위치에서 계산한 맨하탄 거리가 같을 때 왼손잡이이면 "L", 오른손잡이이면 "R"을 추가한다.

     

    function solution(numbers, hand) {
        answer = '';
        leftHandPosition = [0, 0];  // 왼손 시작 좌표
        rightHandPosition = [0, 2]; // 오른손 시작 좌표
        
        // numbers 배열을 좌표에 매칭하기 위한 인덱스화
        numbers.map((num, idx) => {
            if(num === 0) return numbers[idx] = 10
            else return numbers[idx]--
        });
        
        // 키패드를 좌표를 그린다 생각하고 2차원 배열로 표현
        let keyCoordinate = [
                                [3, 0], [3, 1], [3, 2], // 1 2 3
                                [2, 0], [2, 1], [2, 2], // 4 5 6
                                [1, 0], [1, 1], [1, 2], // 7 8 9
                                [0, 0], [0, 1], [0, 2]  // * 0 #
                            ];
        
        numbers.map((_, idx) => numbers[idx] = keyCoordinate[numbers[idx]]);
        
        for(let i = 0; i < numbers.length; i++) {
            // numbers[i]가 1, 4, 7 일때, 왼손위치 numbers[i]로 변경, answer에 L 글자 추가
            if(JSON.stringify(numbers[i]) === JSON.stringify([3, 0]) 
               || JSON.stringify(numbers[i]) === JSON.stringify([2, 0]) 
               || JSON.stringify(numbers[i]) === JSON.stringify([1, 0])
              ) {
                leftHandPosition = numbers[i];
                answer += 'L';
            }
            // numbers[i]가 3, 6, 9 일때, 오른손위치 numbers[i]로 변경, answer에 R 글자 추가
            else if(JSON.stringify(numbers[i]) === JSON.stringify([3, 2])
                    || JSON.stringify(numbers[i]) === JSON.stringify([2, 2])
                    || JSON.stringify(numbers[i]) === JSON.stringify([1, 2])
                   ) {
                rightHandPosition = numbers[i];
                answer += 'R';
            }
            // numbers[i]가 0, 2, 5, 8 일때
            else {
                // 왼손위치와 numbers[i]의 거리가 오른손위치와 numbers[i]의 거리보다 짧을 때
                if(Math.abs(leftHandPosition[0] - numbers[i][0]) + Math.abs(leftHandPosition[1] - numbers[i][1])
                    < Math.abs(rightHandPosition[0] - numbers[i][0]) + Math.abs(rightHandPosition[1] - numbers[i][1])
                  ) {
                    leftHandPosition = numbers[i];
                    answer += 'L';
                }
                // 오른손위치와 numbers[i]의 거리가 왼손위치와 numbers[i]의 거리보다 짧을 때
                else if(Math.abs(leftHandPosition[0] - numbers[i][0]) + Math.abs(leftHandPosition[1] - numbers[i][1])
                        > Math.abs(rightHandPosition[0] - numbers[i][0]) + Math.abs(rightHandPosition[1] - numbers[i][1])
                        ) {
                    rightHandPosition = numbers[i];
                    answer += 'R';
                }
                // 왼손위치와 numbers[i]의 거리와 오른손위치와 numbers[i]의 거리가 같을 때
                else {
                    if(hand === 'left') {
                        leftHandPosition = numbers[i];
                        answer += 'L'
                    }
                    else {
                        rightHandPosition = numbers[i];
                        answer += 'R';
                    }
                }
            }
        }
        return answer;
    }
Designed by Tistory.