본문 바로가기
알고리즘/프로그래머스

[프로그래머스][자바스크립트][Level2][카카오] 방금그곡

by Benjamin_Choi 2022. 2. 16.

풀이

 

/**
 * 방금그곡.js
 * https://programmers.co.kr/learn/courses/30/lessons/17683?language=javascript
 */
 
function solution(m, musicinfos) {
    const resultArr = musicinfos.map((info) => {
        const [start, end, name, scale] = info.split(",");
        const time = calcTime(start, end);
        const scaleArr = replaceStr(scale).split("");

        const sRepeat = Math.floor(time / (scaleArr.length));
        const sRemainder = time % (scaleArr.length);
        const repeatedScale = scaleArr.join("").repeat(sRepeat) + scaleArr.slice(0, sRemainder).join("")

        return { time, repeatedScale, name };
    }).filter((item) => item.repeatedScale.indexOf(replaceStr(m)) > -1).sort((a, b) => b.time - a.time);
    
    if (!resultArr.length) return "(None)";
    
    return resultArr[0].name;
}

function calcTime(start, end) {
    const [sHour, sMinute] = start.split(":").map((item) => parseInt(item));
    const [eHour, eMinute] = end.split(":").map((item) => parseInt(item));

    return (eHour - sHour) * 60 + (eMinute - sMinute);
}

function replaceStr(str) {
    return str.replace(/C#/g, "c").replace(/D#/g, "d").replace(/F#/g, "f").replace(/G#/g, "g").replace(/A#/g, "a");
}

 

치환 안하고 #이 있는 채로 풀다가 애 좀 먹었다. 이후 문제에 주어진 C#, D#, F#, G#, A# 을 모두 소문자로 바꿔줬다. 

치환하지 않고 풀 경우, 반복되는 노래 안에 해당되는 내용을 찾을 때 굉장히 복잡해진다.

치환해주고 풀면 그런 문제 없이 깔끔하게 해결할 수 있다. 

 

주어진 조건에 맞게 차근히 하나씩 처리하면 된다.

 

start와 end로 주어지는 시간을 넘겨서 분단위로 time을 구한다.

넘겨받은 음표도 replaceStr로 #이 붙은 음계들을 소문자로 치환해주고 split으로 쪼개준다. 

이제 음표 갯수와 time을 기반으로 반복되는 멜로디를 repeatedScale 로 만들어준다. 

 

멜로디 m도 replaceStr로 치환해준 뒤,m에서 치환된 string이 반복되는 멜로디 repeatedScale에 존재하는지 indexOf로 확인해서 존재하는 경우만 filtering 해준다.

 

filter 된 내용들은 모두 해당 멜로디를 가진 노래들이므로 문제에 주어진 조건대로 재생시간(time) 을 기준으로 내림차순 정렬해준다.

 

배열이 빈배열이면 "(None)" 으로 return해주고, 값이 있으면 재생시간에 따라 정렬됐으므로 가장 처음에 있는 값의 name을 넘겨주면 끝난다.

댓글