알고리즘/프로그래머스

프로그래머스 - [PCCP 기출문제] 1번 / 동영상 재생기 C++

초심을 찾자 2024. 10. 12. 09:47
SMALL

 오늘은 오랜만에 알고리즘 글을 올리게 되어 가벼운 문제를 풀어보았다. 앞으로 알고리즘 포스팅에는 내가 문제를 푸는데 얼마큼 시간이 소요되었는지 몇 번만에 패스했는지 기재를 할 예정이다. 개발자마다 알고리짐을 푸는 방식이 다르겠지만, 나는 "이거는 DFS다, BFS다" 이렇게 풀기보다는 "문제를 이해하고 풀어보니 DFS였다."에 가까운 스타일이다. 

 

알고리즘 난이도 및 시간 ( ※ 개인적인 의견 )

  • 난이도 : Level 1 ( ※ Min : 0, Max : 10 )
  • 풀이 시간 : 30분
  • 제출 횟수 : 1번
  • 풀이 결과 : Pass

문제 설명

 간단하게 생각하면 리모컨으로 우리 시청하는 동영상 시점을 계산하는 거라고 생각하면 된다. 이 글에서 중요한 중요한 문구는 빨간색으로 밑줄을 친 부분들이다. 

출처 : 프로그래머스

 

제한사항은 따로 우리가 크게 고려해야 할 부분은 없다. 다만 분과 초가 한자리일 경우에 0을 붙여서 표현해야 한다는 부분을 빼고는 다른 특이사항이 없다.

출처 : 프로그래머스


입출력

 첫 번째 예시를 보면 시작 Pos가 13:00이다. 일단 op_start와 op_end 사이가 아니다. 

   - 첫 번째 명령어 Next : 13:00 + 00:10 = 13:10

   - 두 번째 명령어 Prev : 13:10 - 00:10 = 13:00

   - 정답 : 04:17

 두 번째 예시는 시작 Pos가 00:05분이다. op_start와 10초 밖에 차이가 나지 않는다. 

   - 첫 번째 명령어 Prev : 00:05 - 00:10 = 00:00

   - 두 번째 명령어 Next : 00:00 + 00:10 = 00:10

   - 세 번째 명령어 Next : 00:10 + 00:10 = 00:20 -> op_start와 op_end 사이로 op_end로 이동한다.

   - 정답 : 06:55


세 번째 예시는 시작 Pos가 04:05분이다. 처음부터 op_start와 op_end사이기 때문에 04:07분에서 시작한다.

   - 첫 번째 명령어 Next : 04:07 + 00:10 = 04:17

   - 정답 : 04:17

출처 : 프로그래머스


문제 풀이

 나는 일단 String으로 계산하는 것보다 초로 계산하는 게 더 편할 것 같아서 Text를 초로 바꿔주는 함수를 하나 만들었다.

GetTimeFromTextTime이 해당 Function이다.

 

 그 다음에는 정답은 String으로 변환하여야 하기 때문에 초를 String으로 변환해 주는 secondsToString 함수를 하나 만들었다. 해당 함수에서는 우리가 문제를 해석할 때 주의해야 했던 한 자리 분초를 위해 예외처리 사항을 기재하였다.

 

 두 개의 기능으로 사전 준비를 완료한 후에 GetResult라는 함수에서 결과값을 도출하게 된다. 여기서 중요한 점은 op_start와 op_end를 매 번 Check를 해주는 것이 필요하다. 그 이외에는 큰 특이사항은 없다.

#include <string>
#include <vector>

using namespace std;

//================================================
// @ 문자 시간을 초로 Converter하는 함수
uint32_t GetTimeFromTextTime(const string & rText)
//================================================
{
    uint32_t iTotalSeconds = 0;
    if(rText.length() > 4)
    {
        uint32_t iMinute = stoi(rText.substr(0,2));
        iTotalSeconds += iMinute*60;
        uint32_t iSeconds = stoi(rText.substr(3,2));
        iTotalSeconds += iSeconds;
    }
    return iTotalSeconds;
}

//================================================
// @ 초를 문자 시간으로 Converter하는 함수
string secondsToString(const uint32_t &iTotalSeconds)
//================================================
{
    string rTextTime = "";
    uint32_t iMinute = iTotalSeconds / 60;
    uint32_t iSeconds = iTotalSeconds % 60;
    if( iMinute < 10) // 한자리 예외처리
    {
        rTextTime += '0';
        rTextTime += to_string(iMinute);
    }
    else
    {
        rTextTime += to_string(iMinute);
    }
    rTextTime += ':';
    
    if( iSeconds < 10) // 한자리 예외처리
    {
        rTextTime += '0';
        rTextTime += to_string(iSeconds);
    }
    else
    {
        rTextTime += to_string(iSeconds);
    }
    
    return rTextTime;
}

//================================================
// @ 결과값 도출하는 함수
uint32_t GetResult(const uint32_t &iVideo_len, 
                   const uint32_t &ipos,
                   const uint32_t &iop_start,
                   const uint32_t &iop_end,
                   const vector<string> &commands)
//================================================
{
    uint32_t iResultPos = ipos;
    uint32_t iCommandCount = static_cast<uint32_t>(commands.size());
    
    for( uint32_t i = 0 ; i < iCommandCount ; ++i ) // Commands 개수 만큼 For문 
    {
        if(  ( iResultPos <= iop_end)
         && (iResultPos >= iop_start) ) // 오프닝 사이인지 Check
        {
            iResultPos = iop_end;
        }
        
        if( "prev" == commands[i] ) // Prev 명령어인 경우
        {
            if(iResultPos < 10 ) // 예외처리
            {
                iResultPos = 0;
            }
            else
            {
                iResultPos -= 10;
            }
        }
        else if( "next" == commands[i] ) // next 명령어인 경우
        {
            if(iResultPos + 10 > iVideo_len) // 예외처리
            {
                iResultPos = iVideo_len;
            }
            else
            {
                iResultPos += 10;
            }
        }
        else
        {
            /*...*/
        }
    }
    
    if(  ( iResultPos <= iop_end)
         && (iResultPos >= iop_start) ) // 마지막 시간은 for문에서 못했기 때문에 한번 더 체크
    {
        iResultPos = iop_end;
    }
    return iResultPos;
}

string solution(string video_len, string pos, string op_start, string op_end, vector<string> commands) {
    string answer = "";
    uint32_t iVideo_len = GetTimeFromTextTime(video_len);
    uint32_t ipos = GetTimeFromTextTime(pos);
    uint32_t iop_start = GetTimeFromTextTime(op_start);
    uint32_t iop_end = GetTimeFromTextTime(op_end);
    
    uint32_t iResult = GetResult(iVideo_len,ipos,iop_start,iop_end,commands);
    answer = secondsToString(iResult);
    return answer;
}

 

결과

 

문제 링크 : 코딩테스트 연습 - [PCCP 기출문제] 1번 / 동영상 재생기 | 프로그래머스 스쿨 (programmers.co.kr)

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr