본문 바로가기
TIL

[코테연습] [PCCP 기출문제] 1번 / 동영상 재생기

by 크라00 2024. 12. 21.

https://school.programmers.co.kr/learn/courses/30/lessons/340213?language=java

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

문제 타입

  • 문제 타입: 구현 (Simulation), 문자열 처리

문제 분석

  1. 문제의 핵심 요소:
    • 동영상의 시간 정보를 다룬다. 시간은 문자열 "mm:ss" 형식으로 주어지므로 이를 초(second) 단위로 변환하여 계산하는 것이 편리하다.
    • 입력된 명령(commands)에 따라 시간 조정을 수행한다.
    • 오프닝 구간인지 확인하고, 구간에 해당하면 오프닝의 끝 지점으로 강제로 이동한다.
  2. 제약 사항:
    • 시간 범위가 유효한 범위 안에서만 처리된다.
    • 명령의 길이가 최대 100개이므로 시간 조정 로직을 효율적으로 구현해야 한다.
  3. 명령 처리의 순서:
    • commands 배열의 명령을 순차적으로 처리한다.
    • 각각의 명령 처리 시 오프닝 구간에 해당하면 바로 이동해야 한다.
    • 초 단위로 계산하여 동영상의 처음과 끝 범위를 벗어나지 않도록 한다.

문제 풀이

  1. 문자열 시간 변환:
    • "mm:ss" 형식을 초(second)로 변환: total_seconds = mm * 60 + ss
    • 초(second)를 다시 "mm:ss"로 변환: mm = total_seconds // 60, ss = total_seconds % 60
  2. 명령 처리:
    • "prev" 명령: 현재 위치에서 10초를 빼고, 0초를 넘지 않도록 max(0, pos - 10) 처리.
    • "next" 명령: 현재 위치에서 10초를 더하고, 동영상 길이를 넘지 않도록 min(video_len, pos + 10) 처리.
  3. 오프닝 건너뛰기:
    • 이동 후의 위치가 오프닝 구간(op_start ≤ pos ≤ op_end)이면, pos를 op_end + 1로 이동.
  4. 종합 알고리즘:
    • 동영상 길이, 오프닝 시작/끝, 현재 위치를 초 단위로 변환.
    • commands 배열의 명령을 하나씩 처리하며 위치를 업데이트.
    • 최종 위치를 "mm:ss" 형식으로 변환하여 반환.

 

class Solution {
    public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {
        String answer = "";

        // 오프닝 시작 시간과 종료 시간을 초 단위로 변환
        int opSt = strToTime(op_start);
        int opEd = strToTime(op_end);

        // 현재 위치를 초 단위로 변환하고 오프닝 구간일 경우 스킵 처리
        int posTime = skipTime(strToTime(pos), opSt, opEd);

        // 동영상의 전체 길이를 초 단위로 변환
        int maxTime = strToTime(video_len);

        // 명령어 배열(commands)을 순회하며 각 명령어를 처리
        for (String com : commands) {
            if (com.equals("next")) {
                // "next" 명령: 10초 앞으로 이동
                posTime += 10;
            } else if (com.equals("prev")) {
                // "prev" 명령: 10초 뒤로 이동
                posTime -= 10;
            }

            // 현재 위치가 동영상 범위를 벗어나지 않도록 조정
            if (posTime <= 0) {
                posTime = 0; // 동영상 시작 위치로 이동
            } else if (posTime >= maxTime) {
                posTime = maxTime; // 동영상 종료 위치로 이동
            }

            // 이동 후 오프닝 구간에 있으면 스킵 처리
            posTime = skipTime(posTime, opSt, opEd);
        }

        // 최종 위치를 "mm:ss" 형식으로 변환
        answer = timeToStr(posTime);

        return answer;
    }

    // 현재 위치가 오프닝 구간에 포함되면 오프닝 끝 위치로 이동
    int skipTime(int posTime, int opSt, int opEn) {
        if (posTime >= opSt && posTime <= opEn) {
            posTime = opEn; // 오프닝 끝 위치로 이동
        }
        return posTime;
    }

    // 초 단위를 "mm:ss" 문자열 형식으로 변환
    String timeToStr(int time) {
        int min = time / 60; // 분 계산
        int sec = time % 60; // 초 계산
        String minStr = min < 10 ? "0" + min : "" + min; // 두 자리 형식으로 변환
        String secStr = sec < 10 ? "0" + sec : "" + sec; // 두 자리 형식으로 변환
        return minStr + ":" + secStr;
    }

    // "mm:ss" 문자열 형식을 초 단위로 변환
    int strToTime(String str) {
        String[] arr = str.split(":"); // ":" 기준으로 문자열 분리
        int min = Integer.parseInt(arr[0]); // 분을 정수로 변환
        int sec = Integer.parseInt(arr[1]); // 초를 정수로 변환
        return min * 60 + sec; // 분과 초를 합산해 초 단위로 반환
    }
}