Lv1-키패드 누르기

Dev StoryTeller·2020년 12월 12일
0

0. 문제

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

자세한 내용은 해당 사이트에서 확인할 수 있음
(https://programmers.co.kr/learn/courses/30/lessons/67256)


1. 풀이

import java.util.*;

class Solution {
    static int distance(int[] thumb, int[] num) {
        int dis_x = Math.abs(thumb[0] - num[0]);
        int dis_y = Math.abs(thumb[1] - num[1]);
        
        return (dis_x+dis_y);
    }
    
    public String solution(int[] numbers, String hand) {
        // 정답 리스트
        StringBuilder answer = new StringBuilder();
        // 시작점 위치 부여
        int[] l_thumb = {3, 0};
        int[] r_thumb = {3, 2};
        
        // 숫자에 위치 부여
        int[][] num_pos = new int[10][2];
        num_pos[0][0] = 3;
        num_pos[0][1] = 1;
        for(int i=1; i<num_pos.length; i++) {
            num_pos[i][0] = (i-1)/3;
            num_pos[i][1] = (i-1)%3;
        }
        
        // 숫자를 입력받음
        for(int number : numbers) {
            switch(number) {
                case 1:
                case 4:
                case 7:
                    l_thumb = num_pos[number];
                    answer.append("L");
                    break;
                    
                case 3:
                case 6:
                case 9:
                    r_thumb = num_pos[number];
                    answer.append("R");
                    break;
                    
                default:
                    // 엄지와 숫자의 거리 계산
                    int r_dis = distance(r_thumb, num_pos[number]);
                    int l_dis = distance(l_thumb, num_pos[number]);
                    
                    // 거리 비교
                    if(r_dis < l_dis) {
                        r_thumb = num_pos[number];
                        answer.append("R");
                    }
                    else if(r_dis > l_dis) {
                        l_thumb = num_pos[number];
                        answer.append("L");
                    }
                    else {
                        if(hand.equals("right")) {
                            r_thumb = num_pos[number];
                            answer.append("R");
                        }
                        else {
                            l_thumb = num_pos[number];
                            answer.append("L");
                        }
                    }
                    break;
            }
        }
        return answer.toString();
    }
}

2. 설명

버튼에게 위치 부여하기

이 문제의 핵심은 각 버튼에게 어떻게 위치를 부여할 것인가이다.
필자는 2차원 배열로 위치를 나타내었다.
다른 방법도 있겠지만, 배열이 가장 깔끔하다고 생각한다.

// 시작점 위치 부여
int[] l_thumb = {3, 0};
int[] r_thumb = {3, 2};
        
// 숫자에 위치 부여
int[][] num_pos = new int[10][2];
num_pos[0][0] = 3;
num_pos[0][1] = 1;
for(int i=1; i<num_pos.length; i++) {
    num_pos[i][0] = (i-1)/3;
    num_pos[i][1] = (i-1)%3;
}

그 다음부턴 간단하다.
숫자를 하나받고, 손가락 위치를 해당 버튼으로 이동해주면 된다.


조건에 따라 분기 처리

이때 숫자가 1,4,7이냐 3,6,9이냐 2,5,8,0이냐에 따라 달라지므로 이 부분을 분기 처리해주면 되는데, 나는 switch를 사용하였다.

if-else로 처리하면 if부터 차례대로 조건을 검사하며 내려오지만,
switch바로 해당 case로 이동하기 때문이다.

물론 분기가 2개뿐이라 상관은 없겠지만, 가독성 부분에도 switch가 좀 더 낫다고 생각하였다.

// 숫자를 입력받음
for(int number : numbers) {
    switch(number) {
        // 1, 4, 7 처리
        case 1:
        case 4:
        case 7:
            . . .
            break;
        
        // 3, 6, 9 처리
        case 3:
        case 6:
        case 9:
            . . .
            break;
             
        // 2, 5, 8, 0 처리
        default:
            . . .
            break;
    }
}

2, 5, 8, 0 처리

문제를 보면, 버튼에서 각 손가락까지의 거리에 따라 어떤 손으로 누를지가 달라진다.

따라서 distance()를 정의하여 거리를 계산하고, 이를 분기 처리해서 누를 손가락을 정했다.

// 엄지와 숫자 사이의 거리 계산
static int distance(int[] thumb, int[] num) {
    int dis_x = Math.abs(thumb[0] - num[0]);
    int dis_y = Math.abs(thumb[1] - num[1]);
        
    return (dis_x+dis_y);
}

3. 결론

처음 접했을 때 숫자에 위치를 부여하는데 고심하였다.
배열말고 뭔가 더 효율적인 것이 없을까 고민하다 결국 이도저도 아니게 된 것이다.
해보지도 않고 효율성을 따지는 건 좋지 않다.
너무 많이 생각하지 말고, 일단 시도해보자!

두번째는 거리 계산이었다.
distance()의 return값을 "a^2+b^2"의 형태로 썼더니, 13~20까지 모두 테스트 실패하였다.

이 부분은 솔직히 왜 그런지 잘 모르겠다.
제곱으로 인해서 엇나가는 흐름이 뭐가 있는지 생각을 해봐야 할 것 같다.

profile
개발을 이야기하는 개발자입니다.

0개의 댓글