본문 바로가기

Java/프로그래머스

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

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

 

프로그래머스

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

programmers.co.kr

 

 

 

 

 

 

 

- 숫자를 하나씩 처리하여 왼쪽 열 숫자(1,4,7)은 무조건 왼손으로, 오른쪽 열 숫자(3,6,9)는 무조건 오른손으로 누른다

- 가운데 열 숫자(2,5,8,0)은 현재 손 위치와 목표 숫자의 위치 간의 맨해튼 거리를 계산해 가까운 손으로 누른다. 

 

맨해탄 거리(Manhattan Distance)

https://velog.io/@code-10/%EB%A7%A8%ED%95%B4%ED%8A%BC-%EA%B1%B0%EB%A6%ACManhattan-Distance

 

맨해튼 거리(Manhattan Distance)

코딩테스트를 프로그래밍언어나 SQL 구현 문제로 가끔씩 출제 되는 아래의 거리 측정 방법에 대해 알아보자.맨허튼 거리(Manhattan Distance)는 2차원 평면 공간에서 두 점 A와 B 사이의 거리를. 측정하

velog.io

 

-  2차원 평면 공간에서 두 점 p와 q 사이의 거리를 측정하는 방법 중 하나로, 두 점사이의 수평 및 수직 이동 거리의 합으로 정의된다. 

 

- 즉, 맨해튼 거리가 (p1,p2)와 (q1,q2) 사이면 맨해튼 거리 = |p1-p1| + |p2-p2|이다. 

- 여기서 |p| 또는 |q|는 절댓값을 나타내며 수평방향(p) 수직방향(q)의 거리를 모두 더한 값이다. 

 

- 맨해튼 거리는 유클리드 거리와는 다르게 대각선 방향의 이동을 고려하지 않는다. 

- 오로지 수평 및 수직 방향의 이동만을 고려한다. 

 

 

 

 

정답 

 

class Solution {
    public String solution(int[] numbers, String hand) {
        StringBuilder answer = new StringBuilder();
        
        //키패드 배열에서 각 숫자의 좌표를 미리 저장
        int[][] keyPad = {
            {3, 1}, // 0
            {0, 0}, // 1
            {0, 1}, // 2
            {0, 2}, // 3
            {1, 0}, // 4
            {1, 1}, // 5
            {1, 2}, // 6
            {2, 0}, // 7
            {2, 1}, // 8
            {2, 2}, // 9
            {3, 0}, // *
            {3, 2}  // #
        };
        
        int leftPos[] = keyPad[10]; //왼쪽 손 초기 위치
        int rightPos[] = keyPad[11]; //오른쪽 손 초기 위치 
        
        for(int num : numbers)
        {
            if(num==1 || num==4 || num==7){
                //왼쪽 열 숫자
                answer.append("L");
                leftPos = keyPad[num];
            }
            else if(num==3 || num ==6 || num==9)
            {
                //오른쪽 열 숫자
                answer.append("R");
                rightPos = keyPad[num];
            }
            else
            {
                int targetPos[] = keyPad[num]; //가운데 열 숫자 
                
                // 맨해튼 거리 계산
                int leftDist = Math.abs(leftPos[0] - targetPos[0]) + Math.abs(leftPos[1] - targetPos[1]);
                int rightDist = Math.abs(rightPos[0] - targetPos[0]) + Math.abs(rightPos[1] - targetPos[1]);
                
                
                if(leftDist < rightDist)
                {
                    answer.append("L");
                    leftPos = targetPos; //왼손 위치를 현재 숫자로 업데이트
                }
                else if(rightDist < leftDist)
                {
                    answer.append("R");
                    rightPos = targetPos; //오른손 위치를 현재 숫자로 업데이트
                }
                else
                {
                    //거리가 같다면 
                    if(hand.equals("left"))
                    {
                        //왼손잡이는 왼손
                        answer.append("L");
                        leftPos = targetPos;//왼손 위치를 현재 숫자로 업데이트
                    }
                    else
                    {
                        answer.append("R");
                        rightPos = targetPos;//오른손 위치를 현재 숫자로 업데이트
                    }
                }
            }
        }
        
        return answer.toString();
    }
}

 

 

 

다른 사람의 풀이 

 

 

class Solution {
    public String solution(int[] numbers, String hand) {
        String answer = "";
        StringBuilder answerBuilder = new StringBuilder();
        String[][] phone = {
                {"1", "2", "3"},
                {"4", "5", "6"},
                {"7", "8", "9"},
                {"*", "0", "#"},
        };
        int leftX = 3;
        int leftY = 0;
        int rightX = 3;
        int rightY = 2;
        for (int i = 0; i < numbers.length; i++) {
            for (int j = 0; j < phone.length; j++) {
                    for (int k = 0; k < phone[j].length; k++) {
                    if (String.valueOf(numbers[i]).equalsIgnoreCase(phone[j][k])) {
                        System.out.println("number[====="+numbers[i]);
                        if (k == 0) {
                            answerBuilder.append("L");
                            leftX = j;
                            leftY = k;
                        } else if (k == 2) {
                            answerBuilder.append("R");
                            rightX = j;
                            rightY = k;
                        } else {
                            int leftDistinct = Math.abs(j-leftX)+Math.abs(k-leftY);
                            int rightDistinct = Math.abs(j-rightX)+Math.abs(k-rightY);
                            if (leftDistinct > rightDistinct) {
                                answerBuilder.append("R");
                                rightX = j;
                                rightY = k;
                            } else if (leftDistinct < rightDistinct) {
                                answerBuilder.append("L");
                                leftX = j;
                                leftY = k;
                            } else {
                                answerBuilder.append(hand.equalsIgnoreCase("right") ? "R" : "L");
                                if (hand.equalsIgnoreCase("right")) {
                                    rightX = j;
                                    rightY = k;
                                } else {
                                    leftX = j;
                                    leftY = k;
                                }
                            }
                        }
                    }
                }
            }
        }
        answer = String.valueOf(answerBuilder);
        return answer;
    }
}