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

프로그래머스 - 조이스틱 문제 - 자바

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

 

코딩테스트 연습 - 조이스틱

조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다. ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA 조이스틱을 각 방향으로 움직이면 아래와 같습니다. ▲ - 다

programmers.co.kr

 

1. 문자 전체를 A에서 해당 문자를 만드는데 조작횟수를 구한다.

 - 문자에서 - 'A'를 뺀 값과 'Z' - 문자 + 1(A에서 Z가는) 둘 중 작은값이 조작횟수가 됨

 

2. 각 위치에서  

 - 각 위치의 다음 부터 A가 연속으로 있는 갯수를 구함.

 - 처음부터 i번째 까지 갔다가 다시 처음으로 오는 방식과 처음부터 반대로 갔다가 다시 i번째 까지가는 방식 중 min

 - 오른쪽으로만 조작할 경우의 조작횟수, 각 위치에서 좌우로 움직이는 조작횟수 중 min

 - 앞서 구한 문자 조작횟수와 좌우로 이동하는 최소 조작횟수를 더함.

//프로그래머스 - 조이스틱 문제
class Solution {
    static int count(char target) {
        int front = Math.abs(target - 'A');
        int back = 'Z' - target + 1;
        return Math.min(front, back);
    }

    public int solution(String name) {
        int answer = 0;
        int cursor = name.length() - 1;

        for(int i = 0; i < name.length(); i++) {
            answer += count(name.charAt(i));
        }

        for(int i = 0; i <name.length(); i++) {
            int next = i+1;

            while(next < name.length() && name.charAt(next) == 'A') {
                next+=1;
            }

            // i 다음부터 A의 갯수
            int As = next - i - 1;

            // 전체에서 A를 제외하고 움직이는 횟수
            int moveWithoutA = name.length() - As - 1;

            // 처음부터 i번째 까지 왔다가 돌아가는 방식과 처음에 맨뒤로 갔다가 다시 i번째 까지 오는 방식중 작은 값
            int min = Math.min(i, name.length() - next);

            // 돌아가는거 없이 정방향으로 움직인 경우와 name의 각 위치마다 움직여야하는 커서 수들 중 작은 값
            cursor = Math.min(cursor, moveWithoutA + min);
        }
        // 각 자리수를 만들기위해서 필요한 조작 횟수 + 좌우를 최소한으로 조작하는 수
        return answer + cursor;
    }
}