코딩테스트 연습 > PCCP 기출문제 > [PCCP 기출문제] 1번 / 동영상 재생기
https://school.programmers.co.kr/learn/courses/30/lessons/340213
명령 commands는 2가지 명령을 가진다.
명령이 prev 일 경우 -> 현재 위치에서 10초 전으로 이동, 현재 위치가 10초 미만인 경우 영상의 처음 위치로 이동(00:00)
명령이 next 일 경우 -> 현재 위치에서 10초 후로 이동, 현재 위치 +10이 동영상 길이를 넘어갈 경우 동영상 길이로 이동(video_len)
오프닝 건너뛰기 기능 현재 재생 위치가 오프닝 구간(op_start<=현재 재생 위치 <= op_end)일 경우 자동으로 오프닝 끝나는 위치로 이동

각각 명령 command prev일 경우, 수행 시 0보다 작은 경우, 수행 후 오프닝 구간에 있는 경우
명령 command next일 경우, 수행 시 동영상 길이보다 큰 경우, 수행 후 오프닝 구간에 있는 경우를 따져서 수행한다.
class Solution {
public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {
String answer = "";
int p = toSecond(pos); // 현재 위치
int s = toSecond(op_start); // 오프닝 start
int e = toSecond(op_end); // 오프닝 end
int v = toSecond(video_len); // 비디오 길이
if (p >= s && p <= e) { // 오프닝 구간에 있는 경우 현재 위치를 오프닝이 끝나는 위치로 지정
p = e;
}
for (String command: commands) {
if (command.equals("prev")) { // command 가 prev 인 경우
p = Math.max(p - 10, 0); // prev 명령을 수행 했을 때, 0보다 작으면 0으로 지정
} else {
p = Math.min(p + 10, v); // next 명령을 수행 했을 때, 비디오 길이보다 크면 비디오 길이로 지정
}
if (p >= s && p <= e) { // 명령을 수행하고 오프닝 구간에 있는 경우 현재 위치를 오프닝이 끝나는 위치로 지정
p = e;
}
}
return toStringTime(p);
}
public int toSecond(String time) {
String[] tmp = time.split(":");
int m = Integer.parseInt(tmp[0]) * 60;
int s = Integer.parseInt(tmp[1]);
return m + s;
}
public String toStringTime(int p) {
String m = String.format("%02d", (int) Math.floor((double) p / 60));
String s = String.format("%02d", p % 60);
return m + ":" + s;
}
}
Review
class Solution {
public int trans60(String time){
String[] trans = time.split(":");
int minute = Integer.parseInt(trans[0]) * 60;
int second = Integer.parseInt(trans[1]);
return minute + second;
}
public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {
// 결과 return 할 StringBuilder 생성
StringBuilder sb = new StringBuilder();
// 각 argument mm : ss -> 초로 전부 변환
int v_len = trans60(video_len);
int position = trans60(pos);
int start = trans60(op_start);
int end = trans60(op_end);
// commands 순환 하며 명령 수행
for(String command : commands){
// 현재 위치가 오프닝 구간에 있는 경우 현재 위치를 op_end로 설정
if(position >= start && position <= end){
position = end;
}
// prev 명령 수행
if(command.equals("prev")){
if(position -10 < 0){ // 현재 위치에서 10초 전으로 돌렸을 때, 0 보다 작은 경우
position = 0;
}else{
position -= 10; // 나머지 경우
}
}else{
if(position+10 > v_len){
position = v_len;
}else{
position += 10;
}
}
// 명령 수행 후, 현재 위치가 오프닝 구간에 있으면 현재 위치를 op_end로 설정
if(position >= start && position <= end){
position = end;
}
}
// 명령 수행 후 위치를 다시 "mm : ss" 형태로 변환
int minute = position/60;
int second = position%60;
if(minute < 10){
sb.append("0").append(String.valueOf(minute));
}else if(minute == 0){
sb.append("00");
}else{
sb.append(String.valueOf(minute));
}
sb.append(":");
if(second < 10){
sb.append("0").append(String.valueOf(second));
}else if(second == 0){
sb.append("00");
}else{
sb.append(String.valueOf(second));
}
return sb.toString();
}
}
처음 문제를 잘 못 읽어서 오프닝 건너뛰기의 기능을 착각했다. 현재 위치가 오프닝 구간에 있는 경우 무조건 op_end 구간으로 이동해야하나, 나는 next command가 들어와야지 이동이 가능한 줄 알았다.
추가로 이런 문제에선 그냥 변수를 통해서 풀어야겠다.
배열을 조정하려니 머리 속이 복잡해진다.
import java.util.*;
class Solution {
public String solution(String video_len, String pos, String op_start, String op_end, String[] commands) {
StringBuilder sb = new StringBuilder();
// 문자열을 초 단위로 변환
String[] trans = {video_len, pos, op_start, op_end};
int[] trans60 = new int[trans.length];
for (int i = 0; i < trans.length; i++) {
String[] st = trans[i].split(":");
trans60[i] = Integer.parseInt(st[0]) * 60 + Integer.parseInt(st[1]); // [0] video_len, [1] pos, [2] op_start, [3] op_end
}
for (String command : commands) {
if (command.equals("next")) {
int newPos = trans60[1] + 10;
if (newPos >= trans60[0]) { // 동영상 길이를 넘어가면 마지막 위치로 고정
trans60[1] = trans60[0];
}
else if (trans60[1] < trans60[2] && newPos >= trans60[2]) { // next 실행 후 오프닝 시작점을 넘는 경우
trans60[1] = trans60[3] + 10;
}
else if (trans60[1] >= trans60[2] && trans60[1] <= trans60[3]) { // 현재 위치가 오프닝 구간 내에 있으면
trans60[1] = trans60[3] + 10;
}
else {
trans60[1] = newPos;
}
}
else { // "prev"
int newPos = trans60[1] - 10;
if (newPos <= 0) { // 00:00 이하로 내려가면 0초로 설정
trans60[1] = 0;
}
else if (newPos >= trans60[2] && newPos <= trans60[3]) { // prev 실행 후 오프닝 구간에 들어가면
trans60[1] = trans60[2] - 10;
}
else {
trans60[1] = newPos;
}
}
}
// 결과 시간 변환
return String.format("%02d:%02d", trans60[1] / 60, trans60[1] % 60);
}
}
출처
https://blog.ddalkkack.com/2#google_vignette