[JAVA][PCCP 기출문제] 1번 / 동영상 재생기

NoHae·2025년 2월 6일
0

문제 출처

코딩테스트 연습 > PCCP 기출문제 > [PCCP 기출문제] 1번 / 동영상 재생기
https://school.programmers.co.kr/learn/courses/30/lessons/340213

문제 설명

명령 commands는 2가지 명령을 가진다.
명령이 prev 일 경우 -> 현재 위치에서 10초 전으로 이동, 현재 위치가 10초 미만인 경우 영상의 처음 위치로 이동(00:00)
명령이 next 일 경우 -> 현재 위치에서 10초 후로 이동, 현재 위치 +10이 동영상 길이를 넘어갈 경우 동영상 길이로 이동(video_len)

오프닝 건너뛰기 기능 현재 재생 위치가 오프닝 구간(op_start<=현재 재생 위치 <= op_end)일 경우 자동으로 오프닝 끝나는 위치로 이동

접근 방법

각각 명령 command prev일 경우, 수행 시 0보다 작은 경우, 수행 후 오프닝 구간에 있는 경우
명령 command next일 경우, 수행 시 동영상 길이보다 큰 경우, 수행 후 오프닝 구간에 있는 경우를 따져서 수행한다.

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

        String answer = "";
        int p = toSecond(pos); // 현재 위치
        int s = toSecond(op_start); // 오프닝 start
        int e = toSecond(op_end); // 오프닝 end
        int v = toSecond(video_len); // 비디오 길이

        if (p >= s && p <= e) { // 오프닝 구간에 있는 경우 현재 위치를 오프닝이 끝나는 위치로 지정
            p = e;
        }

        for (String command: commands) {
            if (command.equals("prev")) { // command 가 prev 인 경우
                p = Math.max(p - 10, 0); // prev 명령을 수행 했을 때, 0보다 작으면 0으로 지정
            } else {
                p = Math.min(p + 10, v); // next 명령을 수행 했을 때, 비디오 길이보다 크면 비디오 길이로 지정
            }
            if (p >= s && p <= e) { // 명령을 수행하고 오프닝 구간에 있는 경우 현재 위치를 오프닝이 끝나는 위치로 지정
                p = e;
            }
        }

        return toStringTime(p);
    }

    public int toSecond(String time) {
        String[] tmp = time.split(":");
        int m = Integer.parseInt(tmp[0]) * 60;
        int s = Integer.parseInt(tmp[1]);
        return m + s;
    }

    public String toStringTime(int p) {
        String m = String.format("%02d", (int) Math.floor((double) p / 60));
        String s = String.format("%02d", p % 60);
        return m + ":" + s;
    }

}

Review

class Solution {
    public int trans60(String time){
        String[] trans = time.split(":");
        int minute = Integer.parseInt(trans[0]) * 60;
        int second = Integer.parseInt(trans[1]);
        return minute + second;
    }
    public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {
        // 결과 return 할 StringBuilder 생성
        StringBuilder sb = new StringBuilder();

        // 각 argument mm : ss -> 초로 전부 변환
        int v_len = trans60(video_len);
        int position = trans60(pos);
        int start = trans60(op_start);
        int end = trans60(op_end);

        // commands 순환 하며 명령 수행
        for(String command : commands){
            // 현재 위치가 오프닝 구간에 있는 경우 현재 위치를 op_end로 설정
            if(position >= start && position <= end){
                position = end;
            }

            // prev 명령 수행
            if(command.equals("prev")){
                if(position -10 < 0){ // 현재 위치에서 10초 전으로 돌렸을 때, 0 보다 작은 경우
                    position = 0;
                }else{
                    position -= 10; // 나머지 경우
                }
            }else{
                if(position+10 > v_len){
                    position = v_len;
                }else{
                    position += 10;
                }
            }
            // 명령 수행 후, 현재 위치가 오프닝 구간에 있으면 현재 위치를 op_end로 설정
            if(position >= start && position <= end){
                position = end;
            }
        }

        // 명령 수행 후 위치를 다시 "mm : ss" 형태로 변환
        int minute = position/60;
        int second = position%60;

        if(minute < 10){
            sb.append("0").append(String.valueOf(minute));
        }else if(minute == 0){
            sb.append("00");
        }else{
            sb.append(String.valueOf(minute));
        }

        sb.append(":");
        if(second < 10){
            sb.append("0").append(String.valueOf(second));
        }else if(second == 0){
            sb.append("00");
        }else{
            sb.append(String.valueOf(second));
        }

        return sb.toString();

    }
}

알게된 점

처음 문제를 잘 못 읽어서 오프닝 건너뛰기의 기능을 착각했다. 현재 위치가 오프닝 구간에 있는 경우 무조건 op_end 구간으로 이동해야하나, 나는 next command가 들어와야지 이동이 가능한 줄 알았다.

추가로 이런 문제에선 그냥 변수를 통해서 풀어야겠다.
배열을 조정하려니 머리 속이 복잡해진다.

import java.util.*;

class Solution {
    public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {
        StringBuilder sb = new StringBuilder();
        
        // 문자열을 초 단위로 변환
        String[] trans = {video_len, pos, op_start, op_end};
        int[] trans60 = new int[trans.length];

        for (int i = 0; i < trans.length; i++) {
            String[] st = trans[i].split(":");
            trans60[i] = Integer.parseInt(st[0]) * 60 + Integer.parseInt(st[1]); // [0] video_len, [1] pos, [2] op_start, [3] op_end
        }

        for (String command : commands) {
            if (command.equals("next")) {
                int newPos = trans60[1] + 10;

                if (newPos >= trans60[0]) { // 동영상 길이를 넘어가면 마지막 위치로 고정
                    trans60[1] = trans60[0];
                } 
                else if (trans60[1] < trans60[2] && newPos >= trans60[2]) { // next 실행 후 오프닝 시작점을 넘는 경우
                    trans60[1] = trans60[3] + 10;
                }
                else if (trans60[1] >= trans60[2] && trans60[1] <= trans60[3]) { // 현재 위치가 오프닝 구간 내에 있으면
                    trans60[1] = trans60[3] + 10;
                } 
                else {
                    trans60[1] = newPos;
                }
            } 
            else { // "prev"
                int newPos = trans60[1] - 10;

                if (newPos <= 0) { // 00:00 이하로 내려가면 0초로 설정
                    trans60[1] = 0;
                } 
                else if (newPos >= trans60[2] && newPos <= trans60[3]) { // prev 실행 후 오프닝 구간에 들어가면
                    trans60[1] = trans60[2] - 10;
                } 
                else {
                    trans60[1] = newPos;
                }
            }
        }

        // 결과 시간 변환
        return String.format("%02d:%02d", trans60[1] / 60, trans60[1] % 60);
    }
}

출처
https://blog.ddalkkack.com/2#google_vignette

문제푼 흔적

profile
노력 해보려고 하는 사람(00년생 소프트웨어융합학과, 24년 12월 부터 백엔드 및 코테 공부 시작)

0개의 댓글