Algorithm/Simulation

[Python] 프로그래머스 PCCP 기출문제 1번 / 동영상 재생기

코딩쪼앙 2025. 3. 17. 20:31

문제

 

프로그래머스

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

programmers.co.kr

문제 풀이

  • 문제를 따라 구현하면 되는 단순 구현 문제이나, 오프닝 구간 처리에 신경써야한다.
  • 동영상을 재생하기 전 오프닝 구간에 있다면 오프닝이 끝나는 구간으로 이동 후 연산을 시작해야하고, 모든 연산을 마친 후, 오프닝 구간 체크
  • 구현 완료 후 출력 전 한자리 숫자인 경우 앞에 0을 채우기 위해 zfill 함수를 사용하여 출력 형식 변환

문제 상황

  • ✅ 올바른 오프닝 구간 처리를 위해 고려해야 할 사항
    • 현재 시간이 오프닝 구간에 포함되어 있다면, 오프닝이 끝나는 시간으로 이동해야 한다.
    • 오프닝이 시작하는 분과 끝나는 분이 같지 않을 경우도 명확하게 체크해야 한다.
    • 단순히 현재 분 == 오프닝 시작하는 분 또는 현재 분 == 오프닝 끝나는 분만 체크해서는 안 된다.

2. 잘못된 코드와 예외 케이스

if (op_start_mm < pos_mm < op_end_mm or
pos_mm == op_start_mm and pos_ss >= op_start_ss or
pos_mm == op_end_mm and pos_ss < op_end_ss):
    pos_mm = op_end_mm
    pos_ss = op_end_ss
 

두 세번째 줄의 예외 케이스

오프닝 시작 현재 시간 오프닝 끝 문제 상황
04:04 04:12 04:08 현재 시간이 오프닝 끝보다 뒤인데도 불구하고 04:08로 되돌아감
08:02 08:01 08:10 아직 오프닝이 시작되지 않았음에도 불구하고 오프닝 끝으로 이동함

이처럼 예외 처리를 제대로 하지 않으면 현재 위치가 오프닝 구간이 아님에도 불필요하게 이동하거나, 이미 지나간 시간을 다시 오프닝 종료 시점으로 되돌리는 문제가 발생하므로 분기처리를 정확히 해야 할 필요가 있다.

코드

def solution(video_len, pos, op_start, op_end, commands):
    pos_mm, pos_ss = map(int,pos.split(":"))
    op_start_mm, op_start_ss = map(int,op_start.split(":"))
    op_end_mm, op_end_ss = map(int,op_end.split(":"))
    video_mm, video_ss = map(int,video_len.split(":"))
    
     # 시작할 때 오프닝 구간인 경우 고려
    if (op_start_mm < pos_mm < op_end_mm or
        op_start_mm != op_end_mm and op_start_mm == pos_mm and pos_ss >= op_start_ss or
        op_start_mm == pos_mm == op_end_mm and op_start_ss <= pos_ss < op_end_ss or
        op_start_mm != op_end_mm and pos_mm == op_end_mm and pos_ss < op_end_ss):
            pos_mm = op_end_mm
            pos_ss = op_end_ss
    
    print(pos_mm, pos_ss)
    for c in commands:    
        # 1. prev
        if c == 'prev':
            if pos_ss - 10 < 0 and pos_mm > 0:
                pos_mm -= 1
                pos_ss = (pos_ss + 60) - 10
            else:
                pos_ss = max(0, pos_ss - 10)
                
        # 2. next
        elif c == 'next':
            pos_ss += 10
            if pos_ss >= 60:
                pos_ss -= 60
                pos_mm += 1
                
            if pos_mm > video_mm:
                pos_mm = video_mm
                pos_ss = video_ss
            
            if pos_mm == video_mm and pos_ss > video_ss:
                pos_ss = video_ss
                
        if (op_start_mm < pos_mm < op_end_mm or
        op_start_mm != op_end_mm and op_start_mm == pos_mm and pos_ss >= op_start_ss or
        op_start_mm == pos_mm == op_end_mm and op_start_ss <= pos_ss < op_end_ss or
        op_start_mm != op_end_mm and pos_mm == op_end_mm and pos_ss < op_end_ss):
            pos_mm = op_end_mm
            pos_ss = op_end_ss
            
    pos_mm = str(pos_mm)
    pos_ss = str(pos_ss)
    pos_mm = pos_mm.zfill(2)
    pos_ss = pos_ss.zfill(2)
    answer = pos_mm +":"+ pos_ss
    return answer

 

개선된 코드

# prev 계산
pos_ss = max(0, pos_ss - 10)

# next 계산
pos_ss = (pos_ss + 10) % 60

모듈러 연산max 함수를 활용하여 값이 지정된 범위를 벗어나지 않도록 보정한다.