[카카오] 키패드 누르기(프로그래머스)

정승옥(seungok)·2020년 12월 16일
0

프로그래머스

목록 보기
22/40
post-thumbnail

문제설명

  • 왼손과 오른손의 엄지손가락만을 이용해서 숫자를 입력
  • 맨 처음 왼손 엄지손가락은 ( * ), 오른손 엄지손가락은 ( # )에서 시작
  • 규칙
    1) 엄지손가락은 상하좌우 4가지 방향으로 이동할 수 있고 이동 한 칸은 거리 1에 해당
    2) 왼쪽 열 1,4,7을 입력할 때는 왼손 엄지손가락 사용
    3) 오른쪽 열 3,6,9를 입력할 때는 오른손 엄지손가락 사용
    4) 가운데 열 2,5,8,0을 입력할 때는 현재 두 엄지손가락의 위치에서 더 가까운 엄지손가락 사용
    4-1) 두 엄지손가락의 거리가 같다면 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락 사용
  • 순서대로 누른 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인지 나타내는 문자열 hand
  • 각 번호를 누른 엄지손가락이 왼손이지 오른손인지 나타내는 연속된 문자열 반환하기

제한사항

  • numbers 배열의 크기는 1이상 1,000 이하
  • numbers 배열 원소의 값은 0이상 9이하 정수
  • hand는 'left' 또는 'right'
  • 왼손 엄지손가락을 사용할 경우 'L', 오른손 엄지손가락을 사용할 경우 'R'

풀이

function solution(numbers, hand) {
    // 2차원 배열의 키패드
    const keypad = [
        [1,2,3],
        [4,5,6],
        [7,8,9],
        ['*',0,'#']
    ];
    // 누른 번호를 2차원 배열 keypad에서 찾고
    // x값 PosX[0], y값 PosY[0]를 담은 2차원배열 Position 
    const position = numbers.map(num=>{
        const posY = keypad.map((arr,idx)=>{
            if(arr.includes(num))
                return 4-idx;
            return -1;
        }).filter(num=>num !== -1);
        const posX = keypad
        .filter(arr=>arr.includes(num))
        .map(dialogArr=>
             dialogArr.map((dialog,idx)=>{
                if(dialog === num)
                    return idx + 1;
                return -1;
        }).filter(num => num !== -1))[0];
        
        return [posX[0],posY[0]];
    })
    
    const answer = [];
    // 누른 번호들의 좌표가 담긴 배열 position을 돌며 왼손,오른손 엄지손가락의 거리 계산
    // 현재 엄지손가락의 위치 currentPosition, 엄지손가락의 움직일 위치 movePosition
    position.reduce(
        (currentPosition, movePosition)=>{
            // 누를 번호로부터 왼손,오른손 엄지손가락으로부터 거리 leftDis, rightDis
            const leftDis = 
                  Math.abs(currentPosition[0][0] - movePosition[0])+
                  Math.abs(currentPosition[0][1] - movePosition[1]);
            const rightDis =
                  Math.abs(currentPosition[1][0] - movePosition[0])+
                  Math.abs(currentPosition[1][1] - movePosition[1]);
            // 이동하는 x좌표값이 1이면 왼쪽열 1,4,7이므로 'L'
            // 이동하는 x좌표값이 3이면 오른쪽열 3,6,9이므로 'R'
            if(movePosition[0] === 1){
                answer.push('L');
                return [movePosition, currentPosition[1]];
            }else if(movePosition[0] === 3){
                answer.push('R');
                return [currentPosition[0], movePosition];
            }
            // 누르는 번호가 가운데열 2,5,8,0일 경우
            // 거리를 비교해 'L' 또는 'R' 추가
            // 만약 거리가 같다면 오른손잡이인지 왼손잡이인지 확인
          	else{
                if(leftDis < rightDis) answer.push('L');
                if(leftDis > rightDis) answer.push('R');
                if(leftDis === rightDis){
                    if(hand === 'right') answer.push('R');
                    else answer.push('L');
                }
                // 오른손잡이일때와 왼손잡이일때 비교
                // 오른손잡이일때 거리가 같거나 가까우면 오른손 엄지손가락 이동
                // 왼손잡이일때 거리가 같거나 가까우면 왼손 엄지손가락 이동
                // 아닐 경우 반대로 결과 반환
                if(hand === 'right'){
                    return leftDis < rightDis
                    ? [movePosition, currentPosition[1]]
                    : [currentPosition[0], movePosition];
                }
                return leftDis <= rightDis
                ? [movePosition, currentPosition[1]]
                : [currentPosition[0], movePosition];
            }
        },
        [[1,1],[3,1]]
    );
    return answer.join('');
}

체크포인트

  • 2차원 배열과 map메서드를 이용하여 각 번호들의 좌표값을 구한다
  • reduce메서드
    1) 왼손,오른손 엄지손가락의 초기 위치를 설정
    2) 현재 엄지손가락의 위치와 이동위치를 비교하며 업데이트
profile
Front-End Developer 😁

0개의 댓글