코딩 테스트/프로그래머스

프로그래머스 - 키패드 누르기 문제 (자바)

programmers.co.kr/learn/courses/30/lessons/67256

 

코딩테스트 연습 - 키패드 누르기

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

programmers.co.kr

1단계 문제 이지만 시간이 좀 걸린 문제인데

이유는

1. 다이얼의 거리가 삼각함수를 통한 거리가 아니라 x 이동량 + y 이동량이라는 점입니다.

2. 다이얼의 위치를 잡아주는 식

 

이 두가지 때문인데

1번은 문제 예시까지 봐야 한다는 것는 교훈을 얻었고

2번의 경우는 아래와 같은 고정 배열을 통해서 풀 수 있으나 하나의 메서드로 구하고 싶어서 시간이 걸렸습니다.

(실제 시험이었다면 고민되는 순간에 바로 아래 방식을 사용했을 거 같습니다.)

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
    };

 

실제 풀이 방식은 간단합니다.

1. Postion class를 만들어서 왼손과 오른손의 위치를 #, * 위치로 초기화 해줍니다.

2. 어느 손으로 보낼지 결정

 - 1, 4, 7 이면 왼손 3, 6, 9 이면 오른손으로 바로 처리

 - 이 외의 경우 두손과의 거리를 계산하고 짧은 손을 움직이고

 - 거리가 같은 경우는 주손을 움직이게 처리

3. append 해주면 끝

class Position {
    int x;
    int y;

    public Position(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getDistance(Position next) {
        return Math.abs(this.x - next.x) + Math.abs(this.y - next.y);
    }
}

class Solution {
    static Position leftHand, rightHand;
    public String solution(int[] numbers, String hand) {
        StringBuilder answer = new StringBuilder();
        char handChar = hand.toUpperCase().charAt(0);

        leftHand = new Position(3, 0);
        rightHand = new Position(3, 2);

        for (int number : numbers) {
            answer.append(whichHand(number, handChar));
        }
        return answer.toString();
    }

    public char whichHand(int number, char handChar) {
        Position nextPosition = getNextPosition(number);
        if(number == 1 || number == 4 || number == 7) {
            leftHand = nextPosition;
            return 'L';
        }
        if(number == 3 || number == 6 || number == 9){
            rightHand = nextPosition;
            return 'R';
        }

        int leftDistance = leftHand.getDistance(nextPosition);
        int rightDistance = rightHand.getDistance(nextPosition);

        if(leftDistance < rightDistance) {
            leftHand = nextPosition;
            return 'L';
        }

        if(leftDistance > rightDistance) {
            rightHand = nextPosition;
            return 'R';
        }

        if(handChar == 'L') {
            leftHand = nextPosition;
        }else {
            rightHand = nextPosition;
        }
        return handChar;
    }

    public Position getNextPosition(int number) {
        if (number == 0) {
            return new Position(3, 1);
        }

        int x = number / 3;
        int y = number % 3;

        x = y == 0 ? x - 1 : x;
        y = y == 0 ? 2 : y - 1;

        return new Position(x, y);
    }
}