[Programmers] 광고 삽입 바로가기
카카오TV에서 유명한 크리에이터로 활동 중인 죠르디는 환경 단체로부터 자신의 가장 인기있는 동영상에 지구온난화의 심각성을 알리기 위한 공익광고를 넣어 달라는 요청을 받았습니다. 평소에 환경 문제에 관심을 가지고 있던 "죠르디"는 요청을 받아들였고 광고효과를 높이기 위해 시청자들이 가장 많이 보는 구간에 공익광고를 넣으려고 합니다. "죠르디"는 시청자들이 해당 동영상의 어떤 구간을 재생했는 지 알 수 있는 재생구간 기록을 구했고, 해당 기록을 바탕으로 공익광고가 삽입될 최적의 위치를 고를 수 있었습니다.
참고로 광고는 재생 중인 동영상의 오른쪽 아래에서 원래 영상과 동시에 재생되는 PIP(Picture in Picture) 형태로 제공됩니다.
다음은 "죠르디"가 공익광고가 삽입될 최적의 위치를 고르는 과정을 그림으로 설명한 것입니다.
"죠르디"의 동영상 재생시간 길이 play_time, 공익광고의 재생시간 길이 adv_time, 시청자들이 해당 동영상을 재생했던 구간 정보 logs가 매개변수로 주어질 때, 시청자들의 누적 재생시간이 가장 많이 나오는 곳에 공익광고를 삽입하려고 합니다. 이때, 공익광고가 들어갈 시작 시각을 구해서 return 하도록 solution 함수를 완성해주세요. 만약, 시청자들의 누적 재생시간이 가장 많은 곳이 여러 곳이라면, 그 중에서 가장 빠른 시작 시각을 return 하도록 합니다.
play_time | adv_time | logs | result |
---|---|---|---|
"02:03:55" | "00:14:15" | ["01:20:15-01:45:14", "00:40:31-01:00:00", "00:25:50-00:48:29", "01:30:59-01:53:29", "01:37:44-02:02:30"] | "01:30:59" |
"99:59:59" | "25:00:00" | ["69:59:59-89:59:59", "01:00:00-21:00:00", "79:59:59-99:59:59", "11:00:00-31:00:00"] | "01:00:00" |
"50:00:00" | "50:00:00" | ["15:36:51-38:21:49", "10:14:18-15:36:51", "38:21:49-42:51:45"] | "00:00:00" |
입출력 예 #1
문제 예시와 같습니다.
입출력 예 #2
01:00:00에 공익광고를 삽입하면 26:00:00까지 재생되며, 이곳이 가장 좋은 위치입니다. 이 구간의 시청자 누적 재생시간은 다음과 같습니다.
입출력 예 #3
동영상 재생시간과 공익광고 재생시간이 같으므로, 삽입할 수 있는 위치는 맨 처음(00:00:00)이 유일합니다.
sum()
을 통해 구해 준 다음 다음 값은 앞의 원소는 제거하고, 뒤의 원소를 추가하는 방식을 이용할 수 있다.def convertStringIntoSec(string):
hour, minute, second = map(int,string.split(':'))
return hour * 3600 + minute * 60 + second
HH:MM:SS
형식의 문자열(string
)을 초(second
) 단위의 정수로 변환한 후 반환한다.def convertSecIntoString(sec):
hour = sec // 3600
sec -= 3600 * hour
minute = sec // 60
sec -= 60 * minute
return str(hour).zfill(2) +":"+ str(minute).zfill(2) +":"+ str(sec).zfill(2)
second
) 단위의 정수를 HH:MM:SS
형식의 문자열(string
)로 변환한 후 반환한다.video = [0] * (play_time + 2)
for log in logs:
start, end = log.split('-')
video[convertStringIntoSec(start)+1] += 1
video[convertStringIntoSec(end)+1] -= 1
for i in range(play_time):
video[i+1] += video[i]
play_time
) 크기의 배열(video
)을 생성한다.viedo
)에서 시청자의 동영상 시청 시작에 해당하는 위치(start + 1
)에 값을 1
을 증가시키고, 종료하는 위치(end
)의 값을 1
감소시킨다.totalTime = sum(video[:adv_time+1])
value = totalTime
for start in range(1, play_time - adv_time+1):
totalTime += -video[start] + video[start + adv_time]
if value < totalTime:
value = totalTime
answer = start
0
초부터 시작해서 광고 시간(adv_time
) 크기만큼의 영상에서 누적 시청자 수를 계산한 값을 totalTime
에 갱신한다.value
)의 값도 totalTime
값으로 갱신한다.play_time
)에서 광고 시간(adv_time+1
)을 뺀 값을 시작점으로 하는 광고시간 대비 최고 누적 시창자 수 시간을 계산한다.start
) 1초 이전의 값은 제거 되고 종료 시간(start + adv_time
)에 해당하는 값은 추가하는 방식으로 적용한다.✍ 코드
# 문자열 → 숫자(sec)
def convertStringIntoSec(string):
hour, minute, second = map(int,string.split(':'))
return hour * 3600 + minute * 60 + second
# 숫자(sec) → 문자열
def convertSecIntoString(sec):
hour = sec // 3600
sec -= 3600 * hour
minute = sec // 60
sec -= 60 * minute
return str(hour).zfill(2) +":"+ str(minute).zfill(2) +":"+ str(sec).zfill(2)
def solution(play_time, adv_time, logs):
answer = 0
play_time = convertStringIntoSec(play_time)
adv_time = convertStringIntoSec(adv_time)
# [1] 누적합
video = [0] * (play_time + 2)
for log in logs:
start, end = log.split('-')
video[convertStringIntoSec(start)+1] += 1
video[convertStringIntoSec(end)+1] -= 1
for i in range(play_time):
video[i+1] += video[i]
# [2] 투 포인터
currentTime = sum(video[:adv_time+1])
value = currentTime
for start in range(1, play_time - adv_time+1):
currentTime += -video[start] + video[start + adv_time]
if value < currentTime:
value = currentTime
answer = start
return convertSecIntoString(answer)