본문 바로가기

Algorithm

[프로그래머스] 동영상 재생기 풀어봄

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

 

프로그래머스

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

programmers.co.kr

 

동영상 재생기 문제는 3가지 기능을 지원한다.

이를 보아 3가지 기능을 구현하는 것이 주된 풀이법이라고 생각했다.

 

기능 1. prev 입력 시 10초 전으로 이동, 위치가 10초 미만인 경우 처음으로 이동 (0분 0초)

기능 2. next 입력 시 10초 후로 이동, 남은 시간이 10초 미만인 경우 끝으로 이동 (동영상의 길이와 같음)

기능 3. 현재 재생 위치가 오프닝 구간(op_start 이상 && op_end 이하)인 경우 자동으로 op_end로 이동


여기서 중요하게 본 것은 기능 3이다. 처음에는 잘 이해가 가지 않았는데 언제 어느 타이밍이건 간에 기능 3은 작동한다.

10초 전으로 이동해서 스킵구간이면 자동으로 스킵되고, 10초 후로 이동해서 스킵구간이면 스킵된다.

 

현재 시간이 op_end일 때 prev를 입력하면 10초 전으로 이동하고 다시 스킵해서 op_end로 이동한다는 건데 실제로는 말이 안되는 서비스이지만 뭐 문제니까 이렇게 구현한다.

 


class Solution {
    public int[] getTime(String time) {
        String[] minAndSec = time.split(":");
        int min = Integer.parseInt(minAndSec[0]);
        int sec = Integer.parseInt(minAndSec[1]);
        int[] timeArray = new int[2];
        timeArray[0] = min;
        timeArray[1] = sec;
        return timeArray;
    }

    public String timeToString(int[] time) {
        String string = "";
        if (time[0] < 10) {
            string += "0" + time[0];
        } else {
            string += time[0];
        }
        string += ":";
        if (time[1] < 10) {
            string += "0" + time[1];
        } else {
            string += time[1];
        }
        return string;
    }

    // time1이 time 2보다 작거나 같은지 확인(앞선 시간인지)
    public boolean timeLessThanEqual(int[] time1, int[] time2) {
        // time1은 time2보다 min이 크기 때문에 더 나중 시간
        if (time1[0] > time2[0]) {
            return false;
        } else if(time1[0] < time2[0]) {
            return true;
        }
        else {
            if (time1[1] > time2[1]) {
                return false;
            }
            return true;
        }
    }

    // time1이 time2 보다 큰지 확인 (나중 시간인지)
    public boolean timeGreaterThanEqual(int[] time1, int[] time2) {
        // time1의 min은 time2의 min보다 크기 때문에 나중시간
        if (time1[0] > time2[0]) {
            return true;
        } else if(time1[0] < time2[0]) {
            return false;
        }
        else {
            if (time1[1] >= time2[1]) {
                return true;
            }
            return false;
        }
    }

    public boolean isSkipable(int[] posTime, int[] opStartTime, int[] opEndTime) {
        boolean condition1 = timeGreaterThanEqual(posTime, opStartTime);
        boolean condition2 = timeLessThanEqual(posTime, opEndTime);

        return condition1 && condition2;
    }

    public int[] prev(int[] videoTime, int[] posTime, int[] opStartTime, int[] opEndTime) {
        posTime = skip(posTime, opStartTime, opEndTime);

        posTime[1] -= 10;
        if (posTime[1] < 0) {
            posTime[1] = 60 + posTime[1];
            posTime[0]--;
        }
        if (posTime[0] < 0) {
            posTime[0] = 0;
            posTime[1] = 0;
        }
        return posTime;
    }

    public int[] next(int[] videoTime, int[] posTime, int[] opStartTime, int[] opEndTime) {
        posTime = skip(posTime, opStartTime, opEndTime);

        posTime[1] += 10;
        if (posTime[1] >= 60) {
            posTime[1] = posTime[1] - 60;
            posTime[0]++;
        }
        if (timeGreaterThanEqual(posTime, videoTime)) {
            posTime[0] = videoTime[0];
            posTime[1] = videoTime[1];
        }
        return posTime;
    }

    public int[] skip(int[] posTime, int[] opStartTime, int[] opEndTime) {
        if (isSkipable(posTime, opStartTime, opEndTime)) {
            posTime[1] = opEndTime[1];
            posTime[0] = opEndTime[0];
        }
        return posTime;
    }

    public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {
        int[] videoTime = getTime(video_len);
        int[] posTime = getTime(pos);
        int[] opStartTime = getTime(op_start);
        int[] opEndTime = getTime(op_end);

        for (String command : commands) {
            if (command.equals("prev")) {
                posTime = prev(videoTime, posTime, opStartTime, opEndTime);
            }
            else if (command.equals("next")) {
                posTime = next(videoTime, posTime, opStartTime, opEndTime);
            }
//            System.out.println(Arrays.toString(posTime));
        }
        skip(posTime, opStartTime, opEndTime);
        String answer = timeToString(posTime);
        return answer;
    }
}

입력 받은 시간을 처리하기 위해  getTime 메서드를 통해 [분, 초] 형식으로 반환하고 사용한다.

 

최종 결과를 반환하기 위해 timeToString 메서드를 사용한다.

 

시간의 대소비교를 위해 timeLessThanEqual과 timeGreaterThanEqual 메서드를 만들었다.

 

그리고 스킵이 가능한지 판단하는 boolean 반환 형태의 메서드를 만들었다.

 

기능 1, 2, 3을 각각처리하는 메서드를 만들어 해결했다.

 


다른 풀이로는 시간을 모두 미리 sec로 바꾸고 이를 통해서 해결하는 방법이 있었는데 이것이 훨씬 연산량도 적고 좋은 풀이일 것이라고 생각된다.

 

초가 있을 때 이를 분, 초로 변환하기 위해서는 /와 %를 잘 이용하면 된다는 것을 다시 생각하며 -끝-

'Algorithm' 카테고리의 다른 글

[1일 1CS] TCP  (0) 2026.03.17
[프로그래머스] 메뉴 리뉴얼 풀어봄  (0) 2025.01.17