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

최지나·2023년 11월 1일
1

코딩테스트

목록 보기
62/154

문제

스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.

이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.

  • 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
  • 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
  • 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
  • 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
    • 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.

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

[제한사항]

  • numbers 배열의 크기는 1 이상 1,000 이하입니다.
  • numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다.
  • hand는 "left" 또는 "right" 입니다.
    • "left"는 왼손잡이, "right"는 오른손잡이를 의미합니다.
  • 왼손 엄지손가락을 사용한 경우는 L, 오른손 엄지손가락을 사용한 경우는 R을 순서대로 이어붙여 문자열 형태로 return 해주세요.

입출력 예

numbershandresult
[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"

문제 출처

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

생각

  • 자판을 2차원 배열로 생각하여 0~9까지의 숫자에 position을 부여 (getNumberPosition())
  • 눌러야 하는 숫자가 1, 4, 7에 해당하면 왼손("L")으로 누르고 왼손의 위치를 업데이트
  • 눌러야 하는 숫자가 3, 6, 9에 해당하면 오른손("R")으로 누르고 오른손의 위치를 업데이트
  • 2, 5, 8, 0 중 하나의 숫자를 눌러야 하는 경우 [현재 왼손의 위치 <-> 눌러야 하는 숫자의 위치] 와 [현재 오른손의 위치 <-> 눌러야 하는 숫자의 위치] 를 비교. 같을 경우 hand 정보를 참고 한 뒤 숫자를 누른 손의 위치 업데이트

코드

class Solution {
    public String solution(int[] numbers, String hand) {
        StringBuilder answer = new StringBuilder();
        int[] leftHand = {3, 0};
        int[] rightHand = {3, 2};

        for (int num : numbers) {
            int[] position = getNumberPosition(num);
            if (num == 1 || num == 4 || num == 7) {
                answer.append("L");
                leftHand = position;
            } else if (num == 3 || num == 6 || num == 9) {
                answer.append("R");
                rightHand = position;
            } else {
                int leftDistance = getDistance(leftHand, position);
                int rightDistance = getDistance(rightHand, position);

                if (leftDistance < rightDistance || (leftDistance == rightDistance && hand.equals("left"))) {
                    answer.append("L");
                    leftHand = position;
                } else {
                    answer.append("R");
                    rightHand = position;
                }
            }
        }
        return answer.toString();
    }

    private int[] getNumberPosition(int num) {
        int[] position = new int[2];
        position[0] = (num - 1) / 3;
        position[1] = (num - 1) % 3;
        if (num == 0) {
            position[0] = 3;
            position[1] = 1;
        }
        return position;
    }

    private int getDistance(int[] handPosition, int[] numberPosition) {
        return Math.abs(handPosition[0] - numberPosition[0]) + Math.abs(handPosition[1] - numberPosition[1]);
    }
}

다른 사람의 풀이

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");

    }
}
  • 숫자들의 position을 확인할 때 0 인 경우 11로 임시로 바꿔서 계산하고, 첫 시작 위치 (*, #) 역시 각각 (10, 12) 로 바꿔서 일반화하여 계산한 점이 신기했다 문제에서 주어진 대로만 문제를 풀려고 하는 걸 고치고 싶다 😔
  • 또한 switch문 여러개를 나열 할 수 있는 것도 case 1: case 4: case 7: 처음 알았다 알아둬야겠다!
profile
의견 나누는 것을 좋아합니다 ლ(・ヮ・ლ)

0개의 댓글