프로그래머스 [키패드 누르기] - 67256

2022. 1. 24. 19:11프로그래머스

문제 설명은 다음 링크를 참고해주세요.

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

 

코딩테스트 연습 - 키패드 누르기

[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] "right" "LRLLLRLLRRL" [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] "left" "LRLLRRLLLRR" [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] "right" "LLRLLRLLRL"

programmers.co.kr

1, 4, 7 번은 왼손

3, 6, 9 번은 모두 오른손으로 누릅니다. 위의 6개는 누르는 손이 정해져 있고

2, 5, 8, 0번에서 결과가 달라지게 됩니다.

 

저희가 주목해야 할 부분은 상, 하, 좌, 우 로 한 칸씩 이동이 가능하다는 부분입니다.

숫자패드 12개의 번호 패드를 모두 좌표 평면으로 생각하여, 좌표를 (x, y) 형태로 표현합니다.

	Map<Integer, int[]> map = new HashMap<>();
        int[][] location = { {3,1},
                {0,0},
                {0,1},
                {0,2},
                {1,0},
                {1,1},
                {1,2},
                {2,0},
                {2,1},
                {2,2}
        };

        int[] lLocation = {3,0};
        int[] rLocation = {3,2};

        for(int i= 0 ;i<=9;i++){
            map.put(i, location[i]);
        }

위의 location 배열은 숫자 0 ~ 9 까지의 좌표를 나타낸 것입니다.

제일 위쪽이면서 제일 왼쪽인 숫자 1을 원점(0, 0) 으로 지정하고

아래쪽으로 내려갈 때마다 x좌표: +1,

오른쪽으로 갈 때마다 y좌표: +1  이렇게 지정했습니다. (행, 열을 생각하시면 편합니다.

 

그럼 '*' '#' 은 어디로 갔나요? 좌표 평면에 보이지 않는데요.

그 둘은 시작점에서 출발하고 다시는 거치지 않기 때문에, 맨 처음 따로 지정해줄겁니다.

location 배열에는 포함하지 않았습니다.

 

왼손 엄지의 좌표: (xl, yl)   오른손 엄지의 좌표: (xR, yR) 일 때

우리가 눌러야 할 번호의 좌표를 (x, y)라고 하면

현재 각 엄지로부터 두 사이의 거리는 어떻게 될까요?

 

Ldistance = | xl - x | + | yl - y |

Rdistance = | xR - x | + | yR - y |

 

이렇게 나타낼 수 있을 것입니다.

 

 

최소 거리를 구하는 것이므로 Ldistance, Rdistance 에서 더 작은 값을 선택하면 되겠습니다.

(주의 : Ldistance 와 Rdistance는 우리가 가려는 번호가 2, 5, 8, 0일때만 사용하는 것입니다.)

 

위 코드에서 map의

key값을 번호:0~9 ,

value: 번호의 좌표(2차원 배열) 로 지정해 각 번호의 좌표를 꺼내올 수 있게 했습니다.

 

 

전체 소스 코드

public String solution(int[] numbers, String hand) {
    String result = "";
    Map<Integer, int[]> map = new HashMap<>();
    int[][] location = { {3,1},
            {0,0},
            {0,1},
            {0,2},
            {1,0},
            {1,1},
            {1,2},
            {2,0},
            {2,1},
            {2,2}
    };

    int[] lLocation = {3,0};
    int[] rLocation = {3,2};

    for(int i= 0 ;i<=9;i++){
        map.put(i, location[i]);
    }

    for(int i=0; i<numbers.length; i++){
       int num = numbers[i];

        if(num==1 || num==4 || num==7){ // 1, 4, 7: 왼쪽 엄지로 누름
            result += "L";
            lLocation = map.get(num);
        }
        else if(num== 3|| num==6||num==9){ // 3, 6, 9 : 오른쪽 엄지로 누름
            result += "R";
            rLocation = map.get(num);
        }
        else{ // 2, 5, 8, 0
            int[] numLocation = {map.get(num)[0], map.get(num)[1]};
            int distanceL = Math.abs(numLocation[0] - lLocation[0]) + Math.abs(numLocation[1] - lLocation[1]);
            int distanceR = Math.abs(numLocation[0] - rLocation[0]) + Math.abs(numLocation[1] - rLocation[1]);

            if(distanceL == distanceR){
                if(hand.equals("right")){
                    result += "R";
                    rLocation = map.get(num);
                }else if(hand.equals("left")){
                    result += "L";
                    lLocation = map.get(num);
                }
            }
            else{
                if(distanceL < distanceR){
                    lLocation = map.get(num);
                    result += "L";
                }
                else {
                    rLocation = map.get(num);
                    result += "R";
                }
            }
        }
    }

    return result;
}