[프로그래머스] 동영상 재생기



Programmers - [PCCP 기출문제] 1번 / 동영상 재생기




사용 언어 - C++

소요 시간 - 약 40분




문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/340213




문제 요약

  1. prev : 10초 전으로 이동 / next : 10초 후로 이동
  2. 현재 위치가 10초 이전일 때 prev → 0초로 이동
  3. 현재 위치가 (영상의 총 길이 - 10초) 이후일 때 next → 영상의 끝으로 이동
  4. 오프닝 중인 경우 오프닝의 끝으로 자동 이동
  5. 시간의 표현 00:00




최종 코드

#include <string>
#include <vector>

using namespace std;

int TimeToSeconds(string InTime)
{
    return stoi(InTime.substr(0, 2)) * 60 + stoi(InTime.substr(3, 5)); //시간을 초로 변환
}

string SecondsToTime(int InSeconds)
{
    //앞에 0이 붙지 않는 문제 -> 분이나 초가 10보다 작다면 앞에 0이 필요
    string temp = "";
    temp += ((InSeconds / 60) < 10 ? "0" : "") + to_string(InSeconds / 60);
    temp += ":";
    temp += ((InSeconds % 60) < 10 ? "0" : "") + to_string(InSeconds % 60);
    
    return temp;
}

int CheckIsInOpening(int InPos, int InStart, int InEnd)
{
    if(InStart <= InPos && InPos < InEnd)
        return InEnd;
    
    return InPos;
}

string solution(string video_len, string pos, string op_start, string op_end, vector<string> commands) {
    string answer = "";
    //1. 문자열을 정수로 쪼갠다 -> 어떻게? stoi함수 이용. 
    //2. 시간의 표현. 34분33초를 어떻게 표현할 것인가? 초로 표현 or 분&초 나눠서 표현(변수가 너무 많아짐)
    //3. 34 * 60 + 33으로 표현.
    int videoSeconds = TimeToSeconds(video_len);
    int posSeconds = TimeToSeconds(pos);
    int opStartSeconds = TimeToSeconds(op_start);
    int opEndSeconds = TimeToSeconds(op_end);
    
    //오프닝 중에 오프닝 건너뛰기 (명령 아닌 자동) -> 현재 시간 = op_end
    posSeconds = CheckIsInOpening(posSeconds, opStartSeconds, opEndSeconds);
    
    //commands는 문자열 형태의 배열로 들어옴
    for(string& command : commands)
    {
        if(command == "prev")
        {
            //prev - 10초 전
            posSeconds = max(0, posSeconds - 10);
        }
        else if(command == "next")
        {
            // next - 10초 후(if(+10 > 영상의 마지막), 현재 시간 = 영상의 마지막) -> if 대신 min 함수 사용해보기
            posSeconds = min(videoSeconds, posSeconds + 10);
        }
        else
        {
            continue;
        }
        
        posSeconds = CheckIsInOpening(posSeconds, opStartSeconds, opEndSeconds);
    }
    
    answer = SecondsToTime(posSeconds);
    
    return answer;
}




트러블 슈팅

  • 저번 코테 풀 때, if로 최대 최소를 처리했는데, min과 max라는 함수를 찾아서 해당 함수를 사용해봄
  • 시간을 계산하고 난 후 문자열로 변환할 때, 7분 7초의 경우 7:7로 표현됨 → 시간을 분과 초 단위로 쪼갰을 때 10보다 작다면, 문자열로 표현 시 앞에 0을 붙여줌
  • prev나 next 명령에 의해 오프닝 구간에 진입했을 때, 오프닝 자동 넘기기를 수행하지 않아 최종 출력 시간이 예상 결과값대로 나오지 않음 → next와 prev 명령 후에도 오프닝인지를 체크




해결 과정

  1. string으로 표현된 시간을 int형으로 변환(mm:ss → mm * 60 + ss)
  2. 가장 먼저 체크해야 하는게 무엇인지 생각 → 오프닝 중이라면 오프닝을 넘기는 것이 가장 먼저 수행되어야 함
  3. 영상을 넘기는 명령을 수행
  4. 영상이 넘겨진 후, 오프닝 중이라면 오프닝을 넘김
  5. int형의 시간을 string으로 재변환




문제 풀이 후 소감

  • 시간은 저번 코테 문제 풀이 때와 비슷했지만 조금 더 체계적으로 접근할 수 있었던 것 같음
  • 단계별로 조금 더 세세하게 쪼개서 해결했더니 더 빠른 시간 안에 결과에 도달할 수 있었음
  • 저번 코테를 풀 때는 생각하는 시간보다 코드를 짜는 시간이 오래 걸렸지만, 이번에는 생각하는 시간을 조금 더 길게 가져봄
  • 경험이 쌓이고 생각하는 시간이 줄어들면 다음에는 더 빨리 풀 수 있을지도..?