본문 바로가기
프로그래밍/알고리즘 문제풀이

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

by 노잼인간이라불립니다 2023. 8. 2.

0. 개요

 이번 문제는 위치를 다루는 문제였다. 레벨 1이어도 위치를 다루는 문제는 고민이 조금 필요한 부분이 있다. 다행히 문제가 복잡하지는 않아서 다른 알고리즘 없이 위치를 옮겨다니는 것으로 해결이 가능했다.

 

1. 문제 정의

 휴대폰 키패드에서 앞으로 누르르 번호가 주어 질 때 왼손 엄지와 오른손 엄지로 휴대폰 키패드 번호를 누를 때 마다 L과 R을 추가하여 문자열로 반환하는 문제이다.

 

조건1: 1,4,7 일때는 왼손 엄지로만 누른다.

조건2: 3,6,9 일때는 오른손 엄지로만 누른다.

조건3: 2,5,8,0 일때는 가까운 손가락으로 누른다.

 

2. 내가 한 시도

 1,4,7과 3,6,9를 제외한 2,5,8,0일때 엄지와 누를 키패드의 거리를 비교하는 것이 핵심이 었던 문제 였던 것 같다. 그래서 나는 Location이라는 좌표값을 가진 객체를 만들고, 이 객체에 각 키패드와 엄지손가락의 좌표값을 넣고, 생성해가면서 좌표를 관리하면서 문제를 해결했다.

 

3. code

/**
 * 프로그래머스 LV1
 * 키패드 누르기
 * 접근 방법: 좌표를 가지고 있는 객체를 선언해서 좌표간의 거리를 계산하여 손가락을 움직이면 좋을 것 같다고 생각하고 구현.
 */
public class Solution {

    public String solution(int[] numbers, String hand) {

        /*
         * 제출할 답안
         */
        StringBuilder answer = new StringBuilder();

        /*
         * 인덱스 = 키패드 번호, 엘리먼트 = 좌표로 하여 키패드 배열 선언.
         */
        Location[] keypad = new Location[10];

        /*
         * 손가락의 포지션
         */
        Location leftHandLocation = new Location(3,0);
        Location rightHandLocation = new Location(3,2);

        /*
         * 아까 만든 키패드 배열에 배열에 좌표객체를 만들어 넣어줌
         */
        keypad[0] = new Location(3,1);
        int number = 1;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                keypad[number++] = new Location(i, j);
            }
        }

        /*
         * 누를 번호를 순회해가면서 각 조건에 맞는 거리계산과 그에 따른 손가락의 위치를 변경시켜 준다.
         */
        for (int i = 0; i < numbers.length; i++) {
            int keypadValue = numbers[i]; // 다음에 누를 번호
            Location nextLocation = keypad[keypadValue]; // 다음에 누를 번호의 좌표정보

            /*
             * 1,4,7 일 경우 왼손으로 누르고 좌표이동
             */
            if (keypadValue == 1 || keypadValue == 4 || keypadValue== 7){
                leftHandLocation.move(nextLocation.getRow(), nextLocation.getCol());
                answer.append("L");
            }
            /*
             * 3,6,9 일 경우 오른손으로 누르고 좌표이동
             */
            else if (keypadValue == 3 || keypadValue == 6 || keypadValue ==9){
                rightHandLocation.move(nextLocation.getRow(), nextLocation.getCol());
                answer.append("R");
            }
            /*
             * 2,5,8,0 일 경우 거리비교 후 좌표이동
             */
            else{
                if(nextLocation.getDistanceWith(leftHandLocation) > nextLocation.getDistanceWith(rightHandLocation) ){
                    rightHandLocation.move(nextLocation.getRow(), nextLocation.getCol());
                    answer.append("R");
                }
                else if(nextLocation.getDistanceWith(leftHandLocation) < nextLocation.getDistanceWith(rightHandLocation)){
                    leftHandLocation.move(nextLocation.getRow(), nextLocation.getCol());
                    answer.append("L");
                }
                else{
                    if(hand.equals("right")){
                        rightHandLocation.move(nextLocation.getRow(), nextLocation.getCol());
                        answer.append("R");
                    }
                    else{
                        leftHandLocation.move(nextLocation.getRow(), nextLocation.getCol());
                        answer.append("L");
                    }
                }

            }
        }
        return answer.toString();
    }

    class Location {
        private int row;
        private int col;


        public Location(int row, int col) {
            this.row = row;
            this.col = col;
        }

        public int getRow() {
            return row;
        }

        public int getCol() {
            return col;
        }

        public void move(int row, int col){
            this.row = row;
            this.col = col;
        }

        public int getDistanceWith(Location compare){
            int row = Math.abs(this.getRow() - compare.getRow());
            int col = Math.abs(this.getCol() - compare.getCol());
            return row+col;
        }

    }

}

 

4. 새로 알게된 것 또는 깨달은 점

 이전에 코딩테스트를 준비할 때도 그렇고, 지금도 그렇지만 아직 좌표를 다루는 문제에 대해서 익숙하지 않은 느낌이다. 이렇게 워밍업을 해주면서 좌표나 거리를 측정해야 하는 문제가 나올 경우에 이런식으로 객체를 만들어 좌표를 관리하는 방법을 연습해야할 것 같다.

 

참조

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