CODING TEST/Programmers
[ Java ] 프로그래머스 level1 340213번 동영상 재생기 (PCCP 기출문제1)
JUNGY00N
2024. 10. 8. 17:22
동영상 재생기 #340213
더보기
제한사항
입출력 예video_lenposop_startop_endcommandsresult
입출력 예 설명
문제 설명
당신은 동영상 재생기를 만들고 있습니다. 당신의 동영상 재생기는 10초 전으로 이동, 10초 후로 이동, 오프닝 건너뛰기 3가지 기능을 지원합니다. 각 기능이 수행하는 작업은 다음과 같습니다.
- 10초 전으로 이동: 사용자가 "prev" 명령을 입력할 경우 동영상의 재생 위치를 현재 위치에서 10초 전으로 이동합니다. 현재 위치가 10초 미만인 경우 영상의 처음 위치로 이동합니다. 영상의 처음 위치는 0분 0초입니다.
- 10초 후로 이동: 사용자가 "next" 명령을 입력할 경우 동영상의 재생 위치를 현재 위치에서 10초 후로 이동합니다. 동영상의 남은 시간이 10초 미만일 경우 영상의 마지막 위치로 이동합니다. 영상의 마지막 위치는 동영상의 길이와 같습니다.
- 오프닝 건너뛰기: 현재 재생 위치가 오프닝 구간(op_start ≤ 현재 재생 위치 ≤ op_end)인 경우 자동으로 오프닝이 끝나는 위치로 이동합니다.
동영상의 길이를 나타내는 문자열 video_len, 기능이 수행되기 직전의 재생위치를 나타내는 문자열 pos, 오프닝 시작 시각을 나타내는 문자열 op_start, 오프닝이 끝나는 시각을 나타내는 문자열 op_end, 사용자의 입력을 나타내는 1차원 문자열 배열 commands가 매개변수로 주어집니다. 이때 사용자의 입력이 모두 끝난 후 동영상의 위치를 "mm:ss" 형식으로 return 하도록 solution 함수를 완성해 주세요.
제한사항
- video_len의 길이 = pos의 길이 = op_start의 길이 = op_end의 길이 = 5
- video_len, pos, op_start, op_end는 "mm:ss" 형식으로 mm분 ss초를 나타냅니다.
- 0 ≤ mm ≤ 59
- 0 ≤ ss ≤ 59
- 분, 초가 한 자리일 경우 0을 붙여 두 자리로 나타냅니다.
- 비디오의 현재 위치 혹은 오프닝이 끝나는 시각이 동영상의 범위 밖인 경우는 주어지지 않습니다.
- 오프닝이 시작하는 시각은 항상 오프닝이 끝나는 시각보다 전입니다.
- 1 ≤ commands의 길이 ≤ 100
- commands의 원소는 "prev" 혹은 "next"입니다.
- "prev"는 10초 전으로 이동하는 명령입니다.
- "next"는 10초 후로 이동하는 명령입니다.
입출력 예video_lenposop_startop_endcommandsresult
"34:33" | "13:00" | "00:55" | "02:55" | ["next", "prev"] | "13:00" |
"10:55" | "00:05" | "00:15" | "06:55" | ["prev", "next", "next"] | "06:55" |
"07:22" | "04:05" | "00:15" | "04:07" | ["next"] | "04:17" |
입출력 예 설명
입출력 예 #1
- 시작 위치 13분 0초에서 10초 후로 이동하면 13분 10초입니다.
- 13분 10초에서 10초 전으로 이동하면 13분 0초입니다.
- 따라서 "13:00"을 return 하면 됩니다.
입출력 예 #2
- 시작 위치 0분 5초에서 10초 전으로 이동합니다. 현재 위치가 10초 미만이기 때문에 0분 0초로 이동합니다.
- 0분 0초에서 10초 후로 이동하면 0분 10초입니다.
- 0분 10초에서 10초 후로 이동하면 0분 20초입니다. 0분 20초는 오프닝 구간이기 때문에 오프닝이 끝나는 위치인 6분 55초로 이동합니다. 따라서 "06:55"를 return 하면 됩니다.
입출력 예 #3
- 시작 위치 4분 5초는 오프닝 구간이기 때문에 오프닝이 끝나는 위치인 4분 7초로 이동합니다. 4분 7초에서 10초 후로 이동하면 4분 17초입니다. 따라서 "04:17"을 return 하면 됩니다.
설명
- Time 클래스를 생성한다.
- min, sec를 인스턴스 변수로
- Time 클래스의 생성자에 mm:ss 으로 파라미터를 넘겨주면 : 를 기준으로 split 하여 각각 분(min), 초(sec)에 저장
- autoMove 메서드는 현재 오프닝 구간에 위치하면 오프닝의 종료로 이동하도록 하는 메서드
- adjust 메서드는 next 또는 prev 명령어에 따라 현재 시각을 조절하며, 0초 미만일 경우 처음으로, 동영상 길이를 벗어나면 동영상의 종료로 이동하도록 하는 메서드
- getTime 메서드는 문제에서 요구하는 형식에 맞게 String객체를 리턴하는 메서드(String.format 사용)
- compareTo 메서드는 Time 객체 간의 비교를 위해 min이 같을 경우 sec로 비교하도록 오버라이드
- 종료시각(end), 현재위치(now), 오프닝시작(opStart), 오프닝끝(opEnd)으로 각각 Time 인스턴스를 생성
- 처음에 autoMove() 를 호출하여 오프닝 구간에 있다면 오프닝 끝으로 이동
- commands 배열을 순회하며
- adjustTime 메소드에 next 면 10을 prev면 -10을 넘겨줌 + 동영상의 종료 시간과 비교하기 위해 End 인스턴스도 넘겨줌
- 시간 조정 후 항상 오프닝 구간에 있는지 확인해야 하므로 autoMove 메소드 호출
- 최종 값을 리턴 (getTime(now))
나의 풀이
import java.util.*;
class Solution {
public class Time implements Comparable<Time>{
public int min;
public int sec;
Time(String mmss){
String[] splited = mmss.split(":");
this.min = Integer.parseInt(splited[0]);
this.sec = Integer.parseInt(splited[1]);
}
public void adjustTime(int sec, Time end){
int totalSec = this.min * 60 + this.sec + sec;
int endSec = end.min * 60 + end.sec;
if(totalSec < 0){
totalSec = 0;
}else if(totalSec >= endSec){
totalSec = endSec;
}
this.min = totalSec / 60;
this.sec = totalSec % 60;
}
public void autoMove(Time end, Time opStart, Time opEnd){
if(this.compareTo(opStart) >= 0 && this.compareTo(opEnd) <= 0){
this.min = opEnd.min;
this.sec = opEnd.sec;
}
}
public String getTime(){
return String.format("%02d", this.min) +":" +String.format("%02d",this.sec);
}
@Override
public int compareTo(Time other){
return this.min == other.min ? this.sec - other.sec : this.min - other.min;
}
}
public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {
Time end = new Time(video_len);
Time now = new Time(pos);
Time opStart = new Time(op_start);
Time opEnd = new Time(op_end);
now.autoMove(end, opStart, opEnd);
for(String cmd : commands){
if(cmd.equals("next")){
now.adjustTime(10, end);
}else if(cmd.equals("prev")){
now.adjustTime(-10, end);
}
now.autoMove(end, opStart, opEnd);
}
String answer = now.getTime();
return answer;
}
}
+ 테스트 케이스 3번이 안되는 문제
=> 오프닝 시작 시간이 00:00인 경우를 고려해보시길 바랍니다.
prev를 해서 첫 위치로 갔을 때, 해당 구간이 오프닝 시작 시간이어서, 오프닝 종료 시각으로 이동해야 함