문제
문제 설명
동영상 재생기를 만드는 문제다.
동영상 재생기에는 3가지 기능을 지원하고 각각의 기능은 다음과 같다.
1. commands[] 의 string 배열 값이 "prev"인 경우 : 동영상을 10초 전으로 이동한다. 만약 현재 위치가 0분 10초 미만인 경우에는 0초로 이동하면 된다.
2. commands[] 의 string 배열 값이 "next"인 경우 : 동영상을 10초 후로 이동한다. 만약 남은 동영상의 길이가 10초 미만인 경우에는 영상의 길이에 해당하는 값으로 이동한다.
3. 오프닝 건너뛰기 기능 : 현재 재생 위치가 오프닝 구간에 해당한다면, 해당 구간을 스킵하는 기능이다.
(op_start <= 현재의 재생 위치 <= op_end이 오프닝 구간에 해당한다.)
주어지는 매개변수는 다음과 같다.
- string video_len = 동영상의 길이
- string pos = 기능이 수행되기 직전의 위치
- string op_start = 오프닝의 시작 위치
- string op_end = 오프닝이 끝나는 위치
- string[] commands = 명령어의 배열("prev", "next)
입출력 예 1번 문제의 경우에서 주어지는 변수의 목록을 살펴보자.
- video_len = "34:33"
- pos = "13:00"
- op_start = "00:55"
- op_end = "02:55"
- commands = ["next", "prev"]
위 예시의 경우에는 34분 33초 비디오에서 기능이 수행되기 직전의 위치는 13분 0초이다.
오프닝 구간은 0분 55초부터 02분 55초까지기 때문에 직전 위치는 오프닝 구간에 해당하지 않는다.
commands는 next와 prev로 10초 후로 이동, 그리고 10초 전으로 다시 이동이기 때문에 동영상의 시간은 그대로이다.
따라서 "13:00" 을 return하면 되는 문제다.
해당 코드
using System;
public class Solution {
public string solution(string video_len, string pos, string op_start, string op_end, string[] commands)
{
// 모든 시간을 초 단위로 변환
int videoLength = ConvertToSeconds(video_len);
int currentPos = ConvertToSeconds(pos);
int opStartTime = ConvertToSeconds(op_start);
int opEndTime = ConvertToSeconds(op_end);
// 각 명령어 처리
for(int i = 0; i < commands.Length; i++)
{
// 현재 위치가 오프닝 구간이면 건너뛰기
if(IsInOpening(currentPos, opStartTime, opEndTime))
{
currentPos = opEndTime;
}
// 명령어에 따른 위치 이동
if(commands[i] == "prev")
{
if(currentPos <= 10)
{
currentPos = 0;
}
else
{
currentPos = currentPos - 10;
}
}
else if(commands[i] == "next")
{
if(currentPos + 10 >= videoLength)
{
currentPos = videoLength;
}
else
{
currentPos = currentPos + 10;
}
}
// 이동 후 다시 오프닝 구간 체크
if(IsInOpening(currentPos, opStartTime, opEndTime))
{
currentPos = opEndTime;
}
}
// 최종 위치를 시간 문자열로 변환하여 반환
return ConvertToTimeString(currentPos);
}
private int ConvertToSeconds(string time) // 시간을 초로 변환 = 13:00 -> 13 * 60 + 00 = 780
{
string[] parts = time.Split(':');
return int.Parse(parts[0]) * 60 + int.Parse(parts[1]);
}
private string ConvertToTimeString(int seconds) // 초를 시간 문자열로 변환 = 780 -> 13:00
{
int minutes = seconds / 60;
seconds = seconds % 60;
return $"{minutes:D2}:{seconds:D2}";
}
private bool IsInOpening(int currentPos, int opStart, int opEnd) // 오프닝 구간인지 검사
{
return currentPos >= opStart && currentPos <= opEnd;
}
}
풀이 방법
위 문제는 시간을 계산하는 문제이고 해당 시간은 string 값으로 넘어온다.
따라서 몇분 몇초에 해당하는 동영상 시간을 초로 일괄적으로 계산하는 함수(ConvertToString())를 만들어 주고 변환된 초를 다시 시간으로 바꿔주는 함수(ConvertToTimeString())를 각각 만들었다.
command의 기능에 따라 시간을 계산하기 전에 모든 시간에 해당하는 변수들은 계산하기 편하게 초에 해당하는 int 값으로 변경했다.
또한 IsOpening이라는 현재 위치가 오프닝 구간에 해당하는지 bool값으로 검사하는 함수를 만들어 command 기능을 수행하기 전에 오프닝 구간인지 검사하고 이동 후에도 검사하여 오프닝 구간에 해당하는 경우에는 무조건 오프닝 구간이 끝나는 시간으로 동영상의 시간을 이동시켰다.
위 기능을 command의 길이 만큼 기능을 돌려주고 모든 계산이 끝난 다음에는 동영상의 시간에 해당하는 currentPos 값을 ConvertToTimeString에 넣으면 시간 문자열로 다시 돌려받을 수 있다.
'코딩테스트' 카테고리의 다른 글
C# [프로그래머스] 멀리 뛰기 (0) | 2025.01.31 |
---|---|
C# [프로그래머스] 모음사전 (0) | 2024.12.09 |
C# [HackerRank] Algorithm(Data Structures) - Equal Stacks (0) | 2024.10.14 |
C# [프로그래머스] Lv.2 괄호 회전하기 (0) | 2024.09.16 |
C# [HackerRank] Algorithm(Data Structures) - Counting Valleys (0) | 2024.09.11 |