프로그래머스_키패드 누르기

LeeYulhee·2023년 8월 15일
0

💻 문제 출처 : 프로그래머스_키패드 누르기

👉 내가 작성한 답


import java.util.*;

class Solution {
    public String solution(int[] numbers, String hand) {
        
        int[][] numberPosition = new int[12][2];
        
        
        for(int i = 0; i < 10; i++) {
            if (i == 0) {
                numberPosition[0] = new int[]{3, 1};
                numberPosition[10] = new int[]{3, 0};
                numberPosition[11] = new int[]{3, 2};
            } else {
                numberPosition[i] = new int[]{(i - 1) / 3, (i - 1) % 3};
            }
        }
        
        StringBuilder sb = new StringBuilder();
        
        int leftThumb = 10;
        int rightThumb = 11;
        
        for(int i : numbers) {
            if (i == 1 || i == 4 || i == 7) {
                sb.append("L");
                leftThumb = i;
            } else if (i == 3 || i == 6 || i == 9) {
                sb.append("R");
                rightThumb = i;
            } else {
                int leftDistance = Math.abs(numberPosition[i][0] - numberPosition[leftThumb][0]) + Math.abs(numberPosition[i][1] - numberPosition[leftThumb][1]);
                int rightDistance = Math.abs(numberPosition[i][0] - numberPosition[rightThumb][0]) + Math.abs(numberPosition[i][1] - numberPosition[rightThumb][1]);
                
                if(leftDistance < rightDistance) {
                    sb.append("L");
                    leftThumb = i;
                } else if (rightDistance < leftDistance) {
                    sb.append("R");
                    rightThumb = i;
                } else {
                    if(hand.equals("right")) {
                        sb.append("R");
                        rightThumb = i;
                    } else {
                        sb.append("L");
                        leftThumb = i;
                    }
                }
            }
        }
        
        return sb.toString();
    }
}

📌 문제 풀이 설명

  • int 2차원 배열을 12행, 2열로 생성
    • 1 - 9, *과 #까지 각각의 좌표 값을 저장할 배열
  • for문으로 0부터 10 미만까지 1씩 증가하며 순회
    • 만약 i가 0이라면
      • 0과 *, #의 좌표 값인 {3, 1}, {3, 0}, {3, 2}를 따로 배열에 넣어 줌
    • 그게 아니라면
      • numberPosition[i]에 int 배열을 생성해서 (i - 1) / 3 값과 (i - 1) % 3 값을 넣어 줌
        • (i - 1) / 3 값과 (i - 1) % 3은 각각의 좌표 값의 규칙
          • 1은 {0, 0}, 2는 {0, 1}, 3은 {0, 2}, 4는 {1, 0} … 이기 때문
  • StringBuilder를 생성하고, 각 손가락의 위치를 저장할 int leftThumb와 rightThumb 변수를 선언하고 *에 해당하는 10과 #에 해당하는 11을 대입
  • 향상된 for문으로 numbers를 순회
    • 만약 i가 1 혹은 4 혹은 7과 같다면
      • StringBuilder에 “L”을 추가하고 leftThumb에 i를 대입
    • 그게 아니고 만약 i가 3혹은 6 혹은 9와 같다면
      • StringBuilder에 “R”을 추가하고 rightThumb에 i를 대입
    • 그게 아니라면
      • int 변수 leftDistance를 선언하고 numbers에 해당하는 y 좌표 값과 leftThumb에 해당하는 y 좌표 값을 뺀 절대값 + numbers에 해당하는 x 좌표 값과 leftThumb에 해당하는 x 좌표 값을 뺀 절대값을 대입
      • int 변수 rightDistance에도 동일하게 계산해서 대입
      • 만약 leftDistance가 rightDistance보다 작으면
        • StringBuilder에 “L”을 추가하고 leftThumb에 i를 대입
      • 만약 rightDistance가 leftDistance보다 작으면
        • StringBuilder에 “R”을 추가하고 rightThumb에 i를 대입
      • 그게 아니라면(leftDistance와 rightDistance가 같은 경우)
        • hand가 right와 같으면
          • StringBuilder에 “R”을 추가하고 rightThumb에 i를 대입
        • 그게 아니라면
          • StringBuilder에 “L”을 추가하고 leftThumb에 i를 대입
  • for문 종료 후 return answer




👉 다른 사람이 작성한 답 - 1


class Solution {
    //        0부터 9까지 좌표 {y,x}
    int[][] numpadPos = {
            {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
    };
    //초기 위치
    int[] leftPos = {3,0};
    int[] rightPos = {3,2};
    String hand;
    public String solution(int[] numbers, String hand) {
        this.hand = (hand.equals("right")) ? "R" : "L";

        String answer = "";
        for (int num : numbers) {
            String Umji = pushNumber(num);
            answer += Umji;

            if(Umji.equals("L")) {leftPos = numpadPos[num]; continue;}
            if(Umji.equals("R")) {rightPos = numpadPos[num]; continue;}
        }
        return answer;
    }

    //num버튼을 누를 때 어디 손을 사용하는가
    private String pushNumber(int num) {
        if(num==1 || num==4 || num==7) return "L";
        if(num==3 || num==6 || num==9) return "R";

        // 2,5,8,0 일때 어디 손가락이 가까운가
        if(getDist(leftPos, num) > getDist(rightPos, num)) return "R";
        if(getDist(leftPos, num) < getDist(rightPos, num)) return "L";

        //같으면 손잡이
        return this.hand;
    }

    //해당 위치와 번호 위치의 거리
    private int getDist(int[] pos, int num) {
        return Math.abs(pos[0]-numpadPos[num][0]) + Math.abs(pos[1]-numpadPos[num][1]);
    }
}

📌 문제 풀이 설명

  • 클래스 변수
    • int 2차원 배열에 각 인덱스(버튼)에 해당하는 좌표 값을 넣고 생성
    • 초기 위치 좌표를 int 배열 leftPos와 rightPos로 생성하고 대입
    • Stirng hand 변수 생성
  • solution 메서드
    - 클래스 변수 hand에 hand 변수가 right와 같으면 R, 아니면 L 대입
    - String answer를 선언하고 “”로 초기화
    - 향상된 for문으로 numbers를 순회
    - String 변수 Umji에 pushNumber 메서드에 numbers의 요소를 넣은 결과를 대입
    - pushNumber 메서드
    - num이 만약 1 혹은 4 혹은 7과 같으면 “L”을 return
    - num이 만약 3 혹은 6 혹은 9와 같으면 “R”을 return
    - 만약 getDist 메서드에 leftPos와 num을 넣은 값이 getDist 메서드에 rightPos와 num을 넣은 값보다 크면 return “R”
    - getDist 메서드
    - leftPos의 좌표 배열과 int num을 매개변수로 받음
    - Math.abs를 이용해 좌표 배열의 y 좌표와 num에 해당하는 좌표 y 값을 뺀 절대값 + Math.abs를 이용해 좌표 배열의 x 좌표와 num에 해당하는 좌표 x 값을 뺀 절대값을 return
    - 위와 반대라면 return “L”
    - 위 if문들에 해당되지 않으면 같은 손잡이인 this.hand(L이나 R이 들어간)를 return
    - answer에 Umji 변수를 더함
    - 만약 Umji가 L과 같다면
    - leftPos에 numPos에서 num에 해당하는 좌표 값을 대입하고 continue로 for문 다음 순회로 감
    - 만약 Umji가 R과 같다면
    - rightPos에 numPos에서 num에 해당하는 좌표 값을 대입하고 continue로 for문 다음 순회로 감
    - for문 종료 후 return answer




👉 다른 사람이 작성한 답 - 2


class Solution {
    int tempL = 10;
    int tempR = 12;
    String myhand;
    public String solution(int[] numbers, String hand) {
        myhand = ((hand.equals("right"))? "R": "L");
        String answer = "";
        for(int i=0 ; i< numbers.length ; i++) {
            switch(numbers[i]) {
                case 1: case 4: case 7:
                    answer += "L";
                    tempL = numbers[i];
                    break;
                case 3: case 6: case 9:
                    answer += "R";
                    tempR = numbers[i];
                    break;
                default:
                    String tempHand = checkHand(numbers[i]);
                    if(tempHand.equals("R"))
                        tempR = numbers[i] + ((numbers[i] == 0)? 11:0);
                    else tempL = numbers[i] + ((numbers[i] == 0)? 11:0);
                    answer += tempHand;
                    break;
            }
        }
        return answer;
    }

    private String checkHand(int tempNum) {
        int leftDistance = 0;
        int rightDistance = 0;
        if(tempNum == 0) tempNum = 11;

        leftDistance = Math.abs((tempNum-1)/3 - (tempL-1)/3) + Math.abs((tempNum-1)%3 - (tempL-1)%3);
        rightDistance = Math.abs((tempNum-1)/3 - (tempR-1)/3) + Math.abs((tempNum-1)%3 - (tempR-1)%3);
        System.out.println(tempNum + ": " + leftDistance + ", " + rightDistance);
        return ((leftDistance == rightDistance)? myhand: (leftDistance > rightDistance)? "R": "L");

    }
}

📌 문제 풀이 설명

  • 클래스 변수
    • int tempL을 선언하고 10으로 초기화, int tempR을 선언하고 12로 초기화
    • String 변수 myhand 선언
  • solution 메서드
    • myhand에 hand가 right와 같으면 R, 아니면 L을 대입
    • String answer를 생성하고 “” 대입
    • for문으로 0부터 numbers의 길이 미만까지 1씩 증가하며 순회
      • switch문으로 numbers[i]의 값을 비교
        • case가 1, 4, 7에 해당하면
          • answer에 L을 더하고 tempL에 numbers[i]를 대입
        • case가 3, 6, 9에 해당하면
          • answer에 R을 더하고 tempR에 numbers[i]를 대입
        • 위 케이스들에 해당하지 않으면
          • Stirng tempHand 변수에 numbers[i]를 인수로 전달한 checkHand 메서드의 결과 값을 대입
            • checkHand 메서드
              • int 변수 leftDistance와 rightDistance를 선언하고 0을 대입
              • 만약 tempNum이 0과 같다면 tempNum에 11을 대입
              • leftDistance에 (tempNum - 1) 을 3으로 나눈 값과 (tempL - 1)을 3으로 나눈 값의 절대 값 + tempNum - 1) 을 3으로 나눈 나머지와 (tempL - 1)을 3으로 나눈 나머지의 절대 값을 대입
                • ⇒ 좌표 값을 가진 배열을 만들지 않고, 좌표 값을 바로 계산해서 사용
              • rightDistance에 (tempNum - 1) 을 3으로 나눈 값과 (tempR - 1)을 3으로 나눈 값의 절대 값 + tempNum - 1) 을 3으로 나눈 나머지와 (tempR - 1)을 3으로 나눈 나머지의 절대 값을 대입
              • leftDistance와 rightDistance가 같다면 myhand를 return하고 그게 아니면 leftDistance가 더 클 때 R, 아니면 L을 return
          • 만약 tempHand가 R과 같다면 numbers[i]에 numbers[i]가 0이라면 + 11, 아니면 + 0을 한 값을 tempR에 대입
          • 아니라면 numbers[i]에 numbers[i]가 0이라면 + 11, 아니면 + 0을 한 값을 tempL에 대입
          • answer에 tempHand를 더함
    • for문 종료 후 return answer
profile
공부 중인 신입 백엔드 개발자입니다

0개의 댓글