프로그래머스 동영상 재생기 풀이: 시간 변환과 시뮬레이션

작성·코드 검증: solve together · 작성 언어: Python

0. 문제 링크와 출처

명령어를 순서대로 반복 처리하고 이동 전후의 경계 조건을 적용해야 하므로 Level 2로 판단했다.

1. 문제 요약

동영상 재생기의 현재 위치에서 사용자의 명령을 순서대로 실행한 뒤 최종 재생 위치를 구하는 문제다. 사용할 수 있는 명령은 다음 두 가지다.

  • prev: 현재 위치에서 10초 전으로 이동한다. 0초보다 앞이면 0초로 이동한다.
  • next: 현재 위치에서 10초 후로 이동한다. 동영상 길이를 넘으면 동영상 마지막 위치로 이동한다.

또한 현재 위치가 오프닝 구간 op_start 이상 op_end 이하라면 오프닝 끝인 op_end로 자동 이동한다. 이 자동 이동은 처음 위치를 확인할 때와 각 명령을 실행한 뒤에 적용해야 한다.

2. 문제 해결에 사용되는 알고리즘이나 자료구조 설명

상태 전이와 경계 처리

문자열 mm:ss를 그대로 다루면 분과 초가 바뀌는 경계에서 조건이 복잡해진다. 모든 시간을 초로 바꾸면 +10, -10, min, max를 그대로 사용할 수 있다.

minute, second = map(int, time.split(':'))
total = minute * 60 + second

최종 결과를 만들 때는 다시 divmod(total, 60)으로 분과 초를 나누고 두 자리 형식으로 출력한다.

명령어 시뮬레이션

초 단위로 바꾼 현재 위치 position을 명령어 배열 순서대로 갱신한다.

  1. 처음 위치가 오프닝 안이면 op_end로 이동한다.
  2. prev면 10초를 빼고 0초 미만이 되지 않도록 한다.
  3. next면 10초를 더하고 영상 길이를 넘지 않도록 한다.
  4. 이동이 끝난 뒤 현재 위치가 오프닝 안인지 다시 확인한다.

명령어가 100개 이하이므로 별도의 복잡한 자료구조 없이 반복문 하나로 충분하다.

복잡도

명령어 개수를 C라고 하면 각 명령을 한 번씩 처리하므로 시간 복잡도는 O(C), 추가 공간 복잡도는 O(1)이다.

오프닝 판정의 적용 시점

오프닝 건너뛰기는 명령어가 아니라 위치에 대한 자동 규칙이다. 따라서 시작 위치를 한 번 확인하고, 각 prev·next 이동이 끝날 때마다 다시 확인해야 한다. 시간은 초로 통일하면 이동과 영상 범위 제한을 같은 수의 연산으로 처리할 수 있다.

오답 접근과 반례

명령 실행 전에만 오프닝을 확인하면 이동 결과가 오프닝 안에 들어온 경우를 놓친다. 예를 들어 현재 위치가 55초이고 next 후 65초가 오프닝 구간 [60, 70]이면, 이동 직후 70초로 건너뛰어야 한다.

3. 문제 해결 코드 (Python)

def solution(video_len, pos, op_start, op_end, commands):
    def to_seconds(time):
        minute, second = map(int, time.split(':'))
        return minute * 60 + second

    def skip_opening(position):
        if op_start <= position <= op_end:
            return op_end
        return position

    video_length = to_seconds(video_len)
    position = to_seconds(pos)
    op_start = to_seconds(op_start)
    op_end = to_seconds(op_end)

    position = skip_opening(position)

    for command in commands:
        if command == 'prev':
            position = max(0, position - 10)
        else:
            position = min(video_length, position + 10)

        position = skip_opening(position)

    minute, second = divmod(position, 60)
    return f'{minute:02d}:{second:02d}'

구현 포인트

  • skip_opening 함수를 처음 위치와 명령 실행 후에 모두 호출한다.
  • prev의 하한은 max(0, position - 10)으로 처리한다.
  • next의 상한은 min(video_length, position + 10)으로 처리한다.
  • op_start와 op_end를 포함하는 구간이므로 <= 비교를 사용한다.
  • f'{minute:02d}:{second:02d}'로 결과를 항상 mm:ss 형식으로 맞춘다.

복사해 실행할 테스트

아래 검사를 풀이 코드 아래에 붙여 python 파일명.py로 실행하면 명령 실행 후 오프닝 자동 이동을 확인할 수 있다.

assert solution("34:33", "13:00", "00:55", "02:55", ["next", "prev"]) == "13:00"
assert solution("07:22", "04:05", "00:15", "04:07", ["next"]) == "04:17"

4. 참고 풀이 비교

  • uely의 풀이는 mm:ss 형식을 초 단위로 변환해 계산한 뒤 다시 시간 문자열로 바꾸는 접근을 설명한다.

다른 풀이 중에는 분과 초를 직접 나누어 60초가 넘을 때 분을 올리는 방식도 있다. 이 글에서는 계산 단위를 처음부터 초로 통일해 분·초 경계에서 발생할 수 있는 조건문을 줄였다.

마무리

이 문제는 복잡한 알고리즘보다 조건을 실행 순서대로 정확히 적용하는 것이 중요하다. mm:ss를 초로 변환하고, 이동 전후의 오프닝 건너뛰기와 영상 범위 제한을 분리해 처리하면 구현이 간결해진다.