programmers - 2020 카카오 - 키패드 누르기

marafo·2020년 9월 18일
0
post-thumbnail

문제 설명

스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.

이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.

∙ 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
∙ 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
∙ 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
∙ 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
∙ 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.

순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

[제한사항]
∙ numbers 배열의 크기는 1 이상 1,000 이하입니다.
∙ numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다.
∙ hand는 "left" 또는 "right" 입니다.
∙ "left"는 왼손잡이, "right"는 오른손잡이를 의미합니다.
∙ 왼손 엄지손가락을 사용한 경우는 L, 오른손 엄지손가락을 사용한 경우는 R을 순서대로 이어붙여 문자열 형태로 return 해주세요.

function solution(numbers, hand) {
    let answer = [];
    let mainHand = (hand === 'right') ? 'R' : 'L';
    let leftHand = '*';
    let leftDistance;
    let rightHand = '#';
    let rightDistance;
    let columnIndex;
    let rowIndex;
    let keyPad = [ [1,2,3], [4,5,6], [7,8,9], ['*',0,'#'] ];
    let i = 0;
    
    function findIndex(input){
        if( input === 0){
            return [3,1];
        }
        for( let a = 0; a < keyPad.length; a++){
            if(keyPad[a].find( key => key === input)){
                columnIndex = a;
                rowIndex = keyPad[a].indexOf(input);
            }
        }
        return [columnIndex, rowIndex];
    }

    while( i < numbers.length){
        if( numbers[i] % 3 === 1){
            answer.push('L');
            leftHand = numbers[i];
        }else if( numbers[i] !== 0 && numbers[i] % 3 === 0){
            answer.push('R');
            rightHand = numbers[i];
        }else{
            leftDistance = Math.abs(findIndex(numbers[i])[0] - findIndex(leftHand)[0] ) + Math.abs(findIndex(numbers[i])[1] - findIndex(leftHand)[1] );
            rightDistance = Math.abs(findIndex(numbers[i])[0] - findIndex(rightHand)[0] ) + Math.abs(findIndex(numbers[i])[1] - findIndex(rightHand)[1] );

            if(leftDistance > rightDistance){
                answer.push('R');
                rightHand = numbers[i];
            }else if(leftDistance === rightDistance){
                answer.push(mainHand);
                mainHand === 'R' ? (rightHand = numbers[i] ) : (leftHand = numbers[i]);
            }else{
                answer.push('L');
                leftHand = numbers[i];
            }
        }
        i++;
    }
    
    answer = answer.join('');
    return answer;
}

거의 다 왔는데 0에 대한 findIndex 함수가 동작이 안되서 한참을 헤맸다. 발견 후에도 왜 안됐는지 몰라 고민하다가 0은 if문을 통해 [3,1]로 설정.

1) hand로 들어온 손을 왼/오 손잡이 mainHand 결정
2) while문 안에서 키패드 행렬의 행만큼 루프 돌리기.
3) 가장 먼저 1,4,7 / 3,6,9를 각각 L,R에 할당
4) 2,5,8,0 일 경우 이전의 L,R에 대한 거리를 계산해서 leftDistance가 크면 R을 answer에 푸시하고 rightDistance가 크면 L을 answer에 푸시한다.
5) 거리가 같을 경우 처음 설정했던 mainHand를 answer에 푸시.
6) 각 케이스에 맞게 왼손 위치, 오른손 위치를 갱신

profile
프론트 개발자 준비

0개의 댓글