My Boundary As Much As I Experienced

[PCCP 코딩테스트 기출문제] 1번 / 동영상 재생기 (Javascript 풀이) 본문

Algorithm

[PCCP 코딩테스트 기출문제] 1번 / 동영상 재생기 (Javascript 풀이)

Bumang 2024. 11. 9. 00:01

https://school.programmers.co.kr/learn/courses/30/lessons/340213

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

문제 수준:

레벨1. 

문제 요약:

동영상 재생기를 만들고 있다.

- 가능한 유저입력은 2개이다.

  - 10초 후로 이동

  - 10초 전으로 이동 커멘드

- 영상이 시작되는 점과 영상이 끝나는 점을 넘길수는 없다.

  - 00:05초에서 10초 이전으로 해봤자 00:00초로만 이동한다.

  - 10:00분 짜리 영상에서 09:55에서 10초 뒤로 가봤자 10:00분으로만 이동한다.

- 오프닝 구간이 존재하는데 이 구간에 들어가면 자동 스킵 설정이 되어 있다. 이때 오프닝이 끝나는 지점으로 이동한다.

  - 00:05 ~ 01:00 오프닝 구간인데 00:10에 들어가면 바로 01:00으로 이동

 

각 케이스마다 영상 길이, 오프닝 시작점과 끝점, 10초 앞/뒤 등의 정보가 주어질 때 최종적인 완료 지점이 어딘지를 찾아라.

 

입출력 예 (입력 / 출력):

 

문제 풀이 전략:

구현문제... 각 기능들을 util함수로 나눠서 제대로 실행시키면 풀린다.

 

- for루프로 10초 뒤로 or 10초 앞으로,

- 영상 범위를 넘어나는가? 보정된 값(영상시작 혹은 영상 끝) : 좌표 유지

- 오프닝 구간에 들어갔는가? 스킵하여 오프닝 끝나는 시점으로 이동 : 좌표 유지

 

내 풀이:

function solution(video_len, pos, op_start, op_end, commands) {    
    const videoLen = makeItSecond(video_len); // 영상길이를 초로 변환
    const opStart = makeItSecond(op_start); // 오프닝 시작 시점을 초로 변환
    const opEnd = makeItSecond(op_end); // 오프닝 끝 시점을 초로 변환
    
    let posNow = makeItSecond(pos); // 현재 위치를 초로 변환
    
    // 테스트 케이스 내 커멘드 반복
    for (let command of commands) {
        posNow = skipOp(posNow, opStart, opEnd) // 오프닝에 들어왔으면 끝지점으로 보내버리는 함수 실행
        if (command === "next") { // 10초 후로 이동 시
            posNow += 10
        } else if (command === "prev") { // 10초 전으로 이동 시
            posNow -= 10 
        }
        posNow = clamp(posNow, videoLen) // 영상 범위를 넘어갔는지 보정
    }
    
    posNow = skipOp(posNow, opStart, opEnd) // 마지막으로 오프닝 시점인지 체크
    return stringifyTime(makeItMinuteBack(posNow)); // 문제가 요구하는 형태로 답 제출
}

// 영상 길이를 넘어가거나 00:00초 이전으로 가려고 하면 보정
function clamp(time, videoLen) {
    if (time < 0) {
        return 0
    }
    
    if (time >= videoLen) {
        return videoLen
    }
    
    return time
}

// 분 -> 초로 변환
function makeItSecond(time) {
    const [minute, second] = time.split(":")  
    return Number(minute) * 60 + Number(second)
}

// 초 -> 분으로 변환
function makeItMinuteBack(time) {
    return { minute: Math.floor(time / 60), second: time % 60 }
}

// 오프닝 시점에 들어갔으면 스킵, 아니면 좌표유지
function skipOp(posNow, opStart, opEnd) {        
    if (opStart <= posNow && posNow <= opEnd) {
        return opEnd
    } else {
        return posNow
    }
}

// 최종 결과값 문자열 포맷으로 변환
function stringifyTime(time) {
    let { minute, second } = time
    
    const paddedMinute = minute.toString().padStart(2, "0")
    const paddedSecond = second.toString().padStart(2, "0")
    
    return `${paddedMinute}:${paddedSecond}`
}