Level 2️⃣ - 방금그곡

2024. 4. 23. 15:43알고리즘/프로그래머스

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

 

프로그래머스

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

programmers.co.kr

🚀문제 해석

  1. 끝난 시각 - 시작 시각의 차이 (diff) 를 구한다.
    1. 분으로 바꿔서 해결한다.
  2. 악보의 길이를 diff보다 길다면 자르고, 짧다면 늘린다.
  3. m이 변경된 악보에 포함되어 있는지 확인한다.
  4. 되어있다면 ret에 넣어준다.
  5. 조건에 일치하는 음악이 여러개라면 정렬한다.
    1. 재생된 시간이 제일 긴 음악부터 정렬한다.
    2. 재생된 시간이 같다면 먼저 입력된 음악부터 정렬한다.
  6. 출력에 맞게 값을 리턴한다.

우선 3번 과정이 가장 까다로웠고 5번 과정을 놓쳐서 테스트에 통과하지 못했다.

이 문제가 까다로웠던 것은 C#, A# 처럼 #이 붙어있는 문자를 하나로 봐야된다는 점이었다.

아이디어가 떠오르지 않아 블로그를 찾아보다가 소문자로 변경하는 아이디어를 보았다.

즉, C#, A# ➡ c, a 이렇게 소문자로 변경하면 된다.

 

그리고 항상 예외처리와 출력형식을 꼼꼼히 확인하자.

+ 정규식 공부하자 이제. 미룰 수 없다.

🛠코드

function solution(m, musicinfos) {
    let ret = [];
    m = format(m);
    //1. 끝난시각 - 시작시각의 차이를 구한다.
    for(let i = 0; i < musicinfos.length; i++){
        let [st, et, title, melody] = musicinfos[i].split(",");
        let diff = getDiff(st, et);
    //2. 악보에 #이 들어간 부분을 소문자로 변경한다.
        melody = format(melody);
    //3. 악보의 길이를 변경한다.
        let n = melody.length;
        // 악보의 길이가 더 길다면 잘라주고 짧으면 늘려준다.
        if(n > diff) melody = melody.substring(0, diff);
        else if(n < diff) {
            let k = diff - n;
            for(let i = 0; i < k; i++){
                melody += melody[i % melody.length];
            }
        }
    // 4. m이 melody에 포함되어있는지 확인한다.
        if(melody.includes(m)) ret.push([i, diff, title]);
    }
    if(!ret.length) return "(None)";
    ret.sort(([i1, diff1, title1], [i2, diff2, title2])=>{
        if(diff1 === diff2) return i1 - i2;
        return diff2 - diff1;
    });
    return ret[0][2];
}

function format(a){
    a = a.replace(/(B#)/g, 'b')
         .replace(/(C#)/g,'c')
         .replace(/(D#)/g,'d')
         .replace(/(F#)/g,'f')
         .replace(/(G#)/g,'g')
         .replace(/(A#)/g,'a');
    
    return a;
}

function getDiff(st, et){
    let [a, b] = st.split(":").map(Number);
    let [c, d] = et.split(":").map(Number);
    
    return (c*60 + d) - (a*60 + b);
}

 

format 함수를 정규식을 사용하지 않고 구현할 수 있다. 그래도 정규식 공부에 필요성을 느꼈다.

function format(a){
    let ret = [];
    for(let i = 0; i < a.length; i++){
        if(a[i] === "#"){
            if(ret[i-1]) ret[i-1] = ret[i-1].toLowerCase();
            ret.push("");
        }
        else ret.push(a[i]);
    }
    
    return ret.filter((elem)=> elem).join("");
}