알고리즘/코딩테스트-Programmers

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

kwang2134 2024. 9. 15. 15:14
728x90
반응형
728x90

[Programmers] PCCP 기출문제 1번 / 동영상 재생기 - LV 1


접근

  • 구현

풀이

PCCP 기출문제 1번 동영상 재생기 문제로 프로그래머스 레벨 1단계 문제이다. 동영상 재생 시 흔히 사용하는 10초 넘기기, 10초 이전, 오프닝 건너뛰기를 구현하는 문제로 동영상 시작과 끝 부분에 남은 시간이 10초 미만일 경우 동영상 시작 0분 0초, 동영상 마지막 위치로 해주어야 하는 익숙한 기능들을 구현하는 문제이다. 시간에 대한 계산이므로 자바 time의 LocalTime 객체를 사용해 문제를 풀어 주었다.

	String[] videoSplit = video_len.split(":");
        LocalTime videoLenTime = getTime(videoSplit);

        String[] posSplit = pos.split(":");
        LocalTime posTime = getTime(posSplit);

        String[] startSplit = op_start.split(":");
        LocalTime opStartTime = getTime(startSplit);

        String[] endSplit = op_end.split(":");
        LocalTime opEndTime = getTime(endSplit);

LocalTime 객체에 할당하기 위해 : 를 기준으로 잘라주었다.

private LocalTime getTime(String[] split) {
        return LocalTime.of(0 ,Integer.parseInt(split[0]), Integer.parseInt(split[1]));
    }

잘라진 문자열을 통해 LocalTime 객체를 만들어주는 부분을 따로 메서드로 뽑았다.

	for (String command : commands) {
            switch (command) {
                case "next" -> {
                    posTime = next(posTime, opStartTime, opEndTime, videoLenTime);
                }
                case "prev" -> {
                    posTime = prev(posTime,  opStartTime, opEndTime);
                }
            }
        }

입력받는 명령을 통해 동영상에 대한 조작을 하는 부분이다. 각 명령 수행 수 현재 시간을 반환하게 만들어 두었다.

private LocalTime prev(LocalTime posTime, LocalTime opStartTime, LocalTime opEndTime) {
        LocalTime tenSecondsStart = LocalTime.of(0 ,0, 10);
        if (posTime.isBefore(tenSecondsStart)) {
            posTime = LocalTime.of(0 ,0, 0);
            if (!posTime.isBefore(opStartTime) && !posTime.isAfter(opEndTime)) {
                posTime = opEndTime;
            }
        } else {
            posTime = posTime.minusSeconds(10);
            if (!posTime.isBefore(opStartTime) && !posTime.isAfter(opEndTime)) {
                posTime = opEndTime;
            }
        }
        return posTime;
    }

10초 전으로 이동하는 명령에 대한 메서드이다. 처음에 제출을 하고 테스트케이스 1번과 7번에 대해 실패가 떠서 원인을 찾다 혹시나 했던 부분이 역시나 가 되었는데 바로 오프닝 건너뛰기에 대한 처리를 어느 정도로 해야 하냐가 문제였다. 오프닝 건너뛰기라는 내용이 있는데 입력 받는 명령에는 오프닝 건너뛰기에 대한 부분은 따로 존재하지 않는다. 그래서 처음에 next로 10초 넘기는 과정에서만 오프닝 건너뛰기 처리를 해주었는데 이 문제에서 요구하는 기준은 현재 시간이 오프닝 범위에 들어가 있다면 무조건 오프닝 마지막으로 넘겨야 하는 것이었다. 그래서 10초 이전 명령을 수행할 때도 오프닝 범위에 걸린다면 오프닝 마지막으로 현재 시간을 옮겨 주어야 했다. 동작 방식은 next와 거의 비슷해 next에서 설명하겠다.

private LocalTime next(LocalTime posTime, LocalTime opStartTime, LocalTime opEndTime, LocalTime videoLenTime) {
        LocalTime tenSecondsEnd = videoLenTime.minusSeconds(10);
        if (posTime.isAfter(tenSecondsEnd)) {
            posTime = videoLenTime;
        } else if (!posTime.isBefore(opStartTime) && !posTime.isAfter(opEndTime)) {
            posTime = opEndTime;
            posTime = posTime.plusSeconds(10);
        } else {
            posTime = posTime.plusSeconds(10);
            if (!posTime.isBefore(opStartTime) && !posTime.isAfter(opEndTime)) {
                posTime = opEndTime;
            }
        }
        return posTime;
    }

 

next 명령의 10초 넘기기 메서드로 동영상의 남은 시간이 10초 미만인지 체크를 위해 전체 길이에서 10초 뺀 비교용 객체를 만들어 준다. LocalTime의 isAfter() 메서드로 현재 시간이 동영상의 총길이 - 10초인 시점보다 뒤에 있는지 체크를 한다.남은 시간이 10초 미만일 경우 현재 시간을 동영상 마지막 위치로 이동시킨다. 두 번째는 오프닝에 대한 처리로 현재 시간이 오프닝 시작 시간 보다 앞에 있지 않고 종료 시간보다 뒤에 있지 않을 경우 오프닝 범위 안에 포함된 것으로 현재 시간을 오프닝 마지막 시간으로 바꾸고 거기에 10초를 넘겨준다. 이미 오프닝 범위안인 경우 오프닝을 건너뛰고 난 뒤 10초를 넘기는 연산을 수행하게 되는 것이다. 그리고 현재 시간이 오프닝 범위 밖인 경우 10초를 넘긴 후에 오프닝 범위에 들어가게 되었는지 마지막으로 체크를 한다.

	DateTimeFormatter formatter = DateTimeFormatter.ofPattern("mm:ss");
        return posTime.format(formatter);

모든 명령 수행이 끝나게 되면 formatter를 통해 문제 표준 출력에 맞춰 반환해 준다.


전체 코드

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

class Solution {
    public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {
        String[] videoSplit = video_len.split(":");
        LocalTime videoLenTime = getTime(videoSplit);

        String[] posSplit = pos.split(":");
        LocalTime posTime = getTime(posSplit);

        String[] startSplit = op_start.split(":");
        LocalTime opStartTime = getTime(startSplit);

        String[] endSplit = op_end.split(":");
        LocalTime opEndTime = getTime(endSplit);

        for (String command : commands) {
            switch (command) {
                case "next" -> {
                    posTime = next(posTime, opStartTime, opEndTime, videoLenTime);
                }
                case "prev" -> {
                    posTime = prev(posTime,  opStartTime, opEndTime);
                }
            }
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("mm:ss");
        return posTime.format(formatter);
    }
    private LocalTime prev(LocalTime posTime, LocalTime opStartTime, LocalTime opEndTime) {
        LocalTime tenSecondsStart = LocalTime.of(0,0, 10);
        if (posTime.isBefore(tenSecondsStart)) {
            posTime = LocalTime.of(0,0, 0);
            if (!posTime.isBefore(opStartTime) && !posTime.isAfter(opEndTime)) {
                posTime = opEndTime;
            }
        } else {
            posTime = posTime.minusSeconds(10);
            if (!posTime.isBefore(opStartTime) && !posTime.isAfter(opEndTime)) {
                posTime = opEndTime;
            }
        }
        return posTime;
    }

    private LocalTime next(LocalTime posTime, LocalTime opStartTime, LocalTime opEndTime, LocalTime videoLenTime) {
        LocalTime tenSecondsEnd = videoLenTime.minusSeconds(10);
        if (posTime.isAfter(tenSecondsEnd)) {
            posTime = videoLenTime;
        } else if (!posTime.isBefore(opStartTime) && !posTime.isAfter(opEndTime)) {
            posTime = opEndTime;
            posTime = posTime.plusSeconds(10);
        } else {
            posTime = posTime.plusSeconds(10);
            if (!posTime.isBefore(opStartTime) && !posTime.isAfter(opEndTime)) {
                posTime = opEndTime;
            }
        }
        return posTime;
    }

    private LocalTime getTime(String[] split) {
        return LocalTime.of(0,Integer.parseInt(split[0]), Integer.parseInt(split[1]));
    }
}

 

728x90