카카오TV에서 유명한 크리에이터로 활동 중인 죠르디는 환경 단체로부터 자신의 가장 인기있는 동영상에 지구온난화의 심각성을 알리기 위한 공익광고를 넣어 달라는 요청을 받았습니다. 평소에 환경 문제에 관심을 가지고 있던 "죠르디"는 요청을 받아들였고 광고효과를 높이기 위해 시청자들이 가장 많이 보는 구간에 공익광고를 넣으려고 합니다. "죠르디"는 시청자들이 해당 동영상의 어떤 구간을 재생했는 지 알 수 있는 재생구간 기록을 구했고, 해당 기록을 바탕으로 공익광고가 삽입될 최적의 위치를 고를 수 있었습니다.
참고로 광고는 재생 중인 동영상의 오른쪽 아래에서 원래 영상과 동시에 재생되는 PIP(Picture in Picture) 형태로 제공됩니다.
다음은 "죠르디"가 공익광고가 삽입될 최적의 위치를 고르는 과정을 그림으로 설명한 것입니다.
"죠르디"의 동영상 재생시간 길이 play_time, 공익광고의 재생시간 길이 adv_time, 시청자들이 해당 동영상을 재생했던 구간 정보 logs가 매개변수로 주어질 때, 시청자들의 누적 재생시간이 가장 많이 나오는 곳에 공익광고를 삽입하려고 합니다. 이때, 공익광고가 들어갈 시작 시각을 구해서 return 하도록 solution 함수를 완성해주세요. 만약, 시청자들의 누적 재생시간이 가장 많은 곳이 여러 곳이라면, 그 중에서 가장 빠른 시작 시각을 return 하도록 합니다.
HH:MM:SS
의 형식을 초로 바꾸는 함수와, 초를 HH:MM:SS
의 형식으로 바꾸는 함수를 작성해준다.play_time
과 adv_time
도 모두 '초'로 바꿔서 따로 저장한다.play_time + 1
만큼의 배열(playbar
)을 만들어주고, Array.prototype.fill()
을 이용하여 모두 0으로 초기화한다. (+1만큼의 사이즈로 만들어주는 이유는 배열의 인덱스가 0부터 시작하기 때문에 나중에 꼬이기 싫어서)logs
를 순회하면서 각 로그를 Array.prototype.split()
을 활용해 [시작시간, 종료시간]으로 분해하여 할당하고, 시작시간과 종료시간 역시 모두 초로 바꿔준다.play_time
의 각 초마다 몇 명의 시청자가 시청중인지를 기록하기 위해 play_time[시작시간]
을 1 증가시키고, play_time[종료시간]
을 1 감소시킨다. playbar
에는 각 초마다 몇 명의 시청자가 영상을 시청중인지 알 수 있는 정보를 담고 있게 된다.playbar
에 담겨있는 정보를 이용하여 playbar
의 각 초마다 모든 시청자들의 '누적 영상 재생시간'을 기록한다. 예를 들어, 1초부터 4초까지 한 명만 영상을 보고있었다면 4초까지의 '누적 영상 재생시간'은 4초, 5초부터 7초까지 두 명이 보고 있었다면 각각 누적 영상 재생시간은 6초, 8초, 10초인 것이다.playbar[adv_time_sec] - playbar[1]
로 초기화한다.i=adv_time_sec + 1
부터 play_time_sec
까지 돌면서, 각 구간의 누적 재생 시간을 구한다. 해당 구간의 누적 재생시간이 최대누적시간보다 크다면, 최대누적시간을 업데이트해주고, 해당 구간의 시작 지점으로 answer를 업데이트해준다.HH:MM:SS
형식으로 바꿔서 리턴해주면 된다.// HH:MM:SS 시각을 초로 변환해주는 함수
function toSecond(timeString) {
let totalSec = 0;
const [hour, min, sec] = timeString.split(":");
totalSec += (~~hour) * 3600;
totalSec += (~~min) * 60;
totalSec += (~~sec);
return totalSec;
}
// 초를 받아서 HH:MM:SS로 변환해주는 함수
function toTimeString(sec) {
let leftTime = sec;
let hour = Math.floor(sec / 3600);
leftTime -= hour * 3600;
let minute = Math.floor(leftTime / 60);
leftTime -= minute * 60;
let second = leftTime;
if(hour < 10) hour = "0" + hour.toString();
else hour = hour.toString();
if(minute < 10) minute = "0" + minute.toString();
else minute = minute.toString();
if(second < 10) second = "0" + second.toString();
else second = second.toString();
return [hour, minute, second].join(":");
}
function solution(play_time, adv_time, logs) {
var answer = '';
let play_time_sec = toSecond(play_time);
let adv_time_sec = toSecond(adv_time);
//초 단위로 나타낸 시간 프로그레스 바
let playbar = Array(play_time_sec + 1).fill(0);
logs.forEach(log => {
const [start, end] = log.split("-");
const startSec = toSecond(start), endSec = toSecond(end);
playbar[startSec]++;
playbar[endSec]--;
});
// 특정 '초'에 몇 명의 사람들이 보고 있었는지를 나타내게 하자.
for(let i=1; i<=play_time_sec; i++) {
playbar[i] += playbar[i-1];
}
// 특정 '초'에 사람들이 해당 비디오를 재생한 누적 재생시간을 나타내게 하자.
for(let i=1; i<=play_time_sec; i++) {
playbar[i] += playbar[i-1];
}
let maxAcc = playbar[adv_time_sec] - playbar[1];
let answerStart = 0;
for(let i=adv_time_sec + 1; i<=play_time_sec; i++) {
let tempAcc = playbar[i] - playbar[i - adv_time_sec];
if(tempAcc > maxAcc) {
maxAcc = tempAcc;
answerStart = i - adv_time_sec + 1;
}
}
answer = toTimeString(answerStart);
return answer;
}
longroadhome 님의 velog (링크)