당신은 동영상 재생기를 만들고 있습니다. 당신의 동영상 재생기는 10초 전으로 이동, 10초 후로 이동, 오프닝 건너뛰기 3가지 기능을 지원합니다. 각 기능이 수행하는 작업은 다음과 같습니다.
동영상의 길이를 나타내는 문자열 video_len, 기능이 수행되기 직전의 재생위치를 나타내는 문자열 pos, 오프닝 시작 시각을 나타내는 문자열 op_start, 오프닝이 끝나는 시각을 나타내는 문자열 op_end, 사용자의 입력을 나타내는 1차원 문자열 배열 commands가 매개변수로 주어집니다. 이때 사용자의 입력이 모두 끝난 후 동영상의 위치를 "mm:ss" 형식으로 return 하도록 solution 함수를 완성해 주세요.
https://school.programmers.co.kr/learn/courses/30/lessons/340213
문제 풀 때 오프닝 구간 처리를 생각하지 못해서 틀렸었다.
작업 이후의 결과값 즉 prev버튼 또는 next버튼이 눌렸을 때 오프닝 구간에 들어갈 경우를
생각하지 못해서 틀렸었다.
작업 시작과 마지막에 해당 경우일 경우 오프닝 마지막 시간으로 이동하는 코드를 작성했더니 테스트 케이스가 잘 통과 되었다.
function solution(video_len, pos, op_start, op_end, commands) {
// 현재 시간을 ms로 변환
const [mm,ss] = pos.split(':');
let currentMs = Number(mm)* 60 + Number(ss);
// 오프닝 시작 시간을 ms로 변환
const [op_start_mm, op_start_ss] = op_start.split(':');
const op_startTime = Number(op_start_mm)* 60 + Number(op_start_ss);
// 오프닝 종료 시간을 ms로 변환
const [op_end_mm, op_end_ss] = op_end.split(':');
const op_endTime = Number(op_end_mm)* 60 + Number(op_end_ss);
// 비디오 길이를 ms로 변환
const [video_len_mm, video_len_ss] = video_len.split(':');
const videoTime = Number(video_len_mm)* 60 + Number(video_len_ss);
// 사용자가 입력한 명령에 따른 next,prev처리
commands.forEach((item)=>{
// 오프닝 구간에 들어가면 오프닝 종료 구간으로 이동
if(op_startTime <= currentMs && currentMs <= op_endTime){
currentMs = op_endTime;
}
if(item === "next"){
currentMs = Math.min(videoTime, currentMs + 10)
} else {
currentMs = Math.max(0,currentMs - 10)
}
// 입력한 명령을 실행한 뒤에도 (명령어가 1개일 경우 때문에 추가)
// 오프닝 구간에 들어가면 오프닝 종료 구간으로 이동
if(op_startTime <= currentMs && currentMs <= op_endTime){
currentMs = op_endTime;
}
})
// 결과를 ms -> "mm:ss"형태로 변형
const [result_mm, result_ss] = [Math.floor(currentMs / 60),currentMs % 60]
// 분 초가 10 미만일때를 위해 추가 (예 08:09)
return `${result_mm < 10 ? '0' + result_mm : result_mm}:${result_ss < 10 ? '0' + result_ss : result_ss}`;
}
일단 테스트 케이스는 모두 성공
이젠 반복되는 작업을 함수로 분리해보겠다.
function solution(video_len, pos, op_start, op_end, commands) {
// 시간 문자열을 ms로 변환
const timeToMs = (time) => {
const [mm,ss] = time.split(':').map(Number);
return mm * 60 + ss
}
let currentMs = timeToMs(pos);
const op_startTimeMs = timeToMs(op_start);
const op_endTimeMS = timeToMs(op_end);
const videoTimeMs = timeToMs(video_len);
// ms를 문자열 시간으로 변환
const resultTimeToMs = (ms) => {
const mm = Math.floor(ms/60);
const ss = ms % 60;
const result = `${mm < 10 ? '0' + mm : mm }:${ss < 10 ? '0' + ss : ss}`
return result
}
commands.forEach((item)=>{
// 구간 체크
if(op_startTimeMs <= currentMs && currentMs <= op_endTimeMS){
currentMs = op_endTimeMS;
}
if(item === "next"){
currentMs = Math.min(videoTimeMs, currentMs + 10)
} else {
currentMs = Math.max(0,currentMs - 10)
}
// 작업 이후 결과값이 오프닝 구간일 경우를 위해 추가
if(op_startTimeMs <= currentMs && currentMs <= op_endTimeMS){
currentMs = op_endTimeMS;
}
})
return resultTimeToMs(currentMs)
}
