1 minute read


sport

코테연습 - kakao 2021 다시풀기

광고 삽입 - 2

누적 재생 시간이 최대가 되도록 광고 삽입하기.

hint

시각과 시간 사이의 문제로 많이 헷갈렸던 것은 사실이지만, 진짜 문제는 알고보니 1 차이 문제가 아니라, copilot이 만든 함수를 아무 생각 없이 그대로 쓴 게 문제였다..

답으로 찾은 시작 초를 다시 시각으로 변환할 때 생성된 함수가 hour를 24로 나눈 나머지를 사용해서 99:59:99까지 표현되지 않는 문제였다.

py solution

# hh:mm:ss to sec
def parse_time(time):
    h, m, s = time.split(':')
    return int(h) * 3600 + int(m) * 60 + int(s)

# sec to hh:mm:ss
def format_time(time):
    sec = time % 60
    time = time // 60
    min = time % 60
    time = time // 60
    hour = time
    return '{:02d}:{:02d}:{:02d}'.format(hour, min, sec)

# calculate where to put adv start for max accumulated play time for logs
def solution(play_time, adv_time, logs):
    """
    play_time: total video time
    adv_time: total ad length
    logs: list of play logs (array of start_time-end_time, ex: "01:20:15-01:45:14")
    all times are in "hh:mm:ss" format
    """

    # sort logs by start time
    logs.sort(key=lambda x: x[0])
    
    # init
    from collections import defaultdict
    marks = defaultdict(int)
    play_time_sec = parse_time(play_time)
    adv_time_sec = parse_time(adv_time)

    # iterate through logs, append start and end time
    for log in logs:
        start, end = log.split('-')
        start = parse_time(start)
        end = parse_time(end)
        marks[start] += 1
        marks[end] -= 1
    
    # use sliding window to mark accumulated play time level for each sec
    acc_play_time = [0] * (play_time_sec+1)
    curr_acc_play_time_level = 0
    for i in range(0, play_time_sec):
        if(i in marks):
            curr_acc_play_time_level += marks[i]
        
        acc_play_time[i] = curr_acc_play_time_level
        pass

    acc_play_time[-1] = 0

    best_adv_start = -1
    best_acc_play_time = 0
    curr_acc_play_time = 0
    curr_adv_start = -1
    curr_adv_end = -1

    # while curr_adv_end is less than adv_time, accumulate initial current adv play time
    while(curr_adv_end < adv_time_sec-1):
        curr_adv_end += 1
        curr_acc_play_time += acc_play_time[curr_adv_end]
        
    best_acc_play_time = curr_acc_play_time
    best_adv_start = 0
    
    while(curr_adv_end < play_time_sec-1):
        curr_adv_end += 1
        curr_adv_start += 1
        curr_acc_play_time -= acc_play_time[curr_adv_start]
        curr_acc_play_time += acc_play_time[curr_adv_end]
        if(curr_acc_play_time > best_acc_play_time):
            best_adv_start = curr_adv_start+1
            best_acc_play_time = curr_acc_play_time

    return format_time(best_adv_start)

그리고 생각해보니 변수 이름이 애매하다. 실제 curr_adv_start / end는 포함하는 구간의 시작과 끝을 포함하는 것이 아니라, start는 구간에서 제외시키는 데 사용하고, end는 구간에 포함시키는 데에 사용한다 window_left 이런 식이 나았을까?


Comments