본문 바로가기

알고리즘 스터디

[Programmers] 카카오 인턴십키패드 누르기 - Javascript

728x90

INDEX

    https://school.programmers.co.kr/learn/courses/30/lessons/67256

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

     

    Solution

    휴대전화 키패드에서 왼쪽 열 [1,4,7,*] 은 왼손으로, 오른쪽 열 [3,6,9,#] 은 오른손으로 입력하고 가운데 열 [2,5,8,0] 은 왼손과 오른손에서 거리가 가까운 손으로 터치하되, 같은 거리면 주어진 hand로 터치를 합니다.

     

    키패드 간의 거리 계산을 위해 좌표 개념을 이용합니다. 숫자 1을 원점 [0, 0]으로 해서 가로와 세로 좌표로 모든 키패드에 있는 숫자를 나타낼 수 있습니다.

    키패드 <1> 은 [0, 0], <2> 는 [0, 1]  이런 식으로 말이죠.

    let positionMap = {
        1: [0, 0],
        2: [0, 1],
        3: [0, 2],
        4: [1, 0],
        5: [1, 1],
        6: [1, 2],
        7: [2, 0],
        8: [2, 1],
        9: [2, 2],
        "*": [3, 0],
        0: [3, 1],
        "#": [3, 2],
      };

    좌표 간의 거리 계산은 간단합니다. 대각선으로 이동을 할 수 없으니 두 점을 잇는 선을 빗변으로 하는 삼각형의 밑변과 높이를 더해주면 됩니다.

     

    예를 들어, <1>과  <5>의 거리를 계산한다면 각 키의 좌표는 다음과 같습니다.

    <1> : [0, 0]

    <5> : [1, 1]

     

    두 점을 잇는 선을 빗변으로 하는 삼각형의 밑변과 높이는 |1 - 0| + |1 - 0| = 2입니다.  

     

    이 개념을 활용해 [2, 5, 8, 0] 의 키패드가 나온 경우 왼손과 오른손이 위치한 키에서부터 거리를 계산해 더 짧은 손을 선택하면 됩니다.

    let answer = [];
    let lastLeftHand = '*';
    let lastRightHand = '#';
    for(const num of numbers){
        if(["1","4","7","*"].includes(num.toString())) {
            answer.push('L');
            lastLeftHand = num;
        }
        else if(["3","6","9","#"].includes(num.toString())) {
            answer.push('R');
            lastRightHand = num;
        }
        else {
            const leftHandPosition = positionMap[lastLeftHand];
            const rightHandPosition = positionMap[lastRightHand];
            const newKeyHandPosition = positionMap[num];
            const distFromLeftHand = Math.abs(newKeyHandPosition[0]-leftHandPosition[0]) + Math.abs(newKeyHandPosition[1]-leftHandPosition[1]);
            const distFromRightHand = Math.abs(newKeyHandPosition[0]-rightHandPosition[0]) + Math.abs(newKeyHandPosition[1]-rightHandPosition[1]);
            if(distFromLeftHand < distFromRightHand){
                lastLeftHand = num;
                answer.push('L');
            }else if(distFromLeftHand === distFromRightHand){
                if(hand === 'left'){
                    lastLeftHand = num;
                    answer.push('L');
                }else{
                    lastRightHand = num;
                    answer.push('R');
                }
            }else{
                lastRightHand = num;
                answer.push('R');
            }
    
        }
    
    }
    return answer.join('');