[프로그래머스] 코딩테스트 연습 - 62

level 2 - 방금그곡

방금그곡 서비스에서는 음악 제목, 재생이 시작되고 끝난 시각, 악보를 제공한다.
네오가 기억한 멜로디와 악보에 사용되는 음은 C, C#, D, D#, E, F, F#, G, G#, A, A#, B 12개이다. 각 음은 1분에 1개씩 재생된다. 음악은 반드시 처음부터 재생되며 음악 길이보다 재생된 시간이 길 때는 음악이 끊김 없이 처음부터 반복해서 재생된다. 음악 길이보다 재생된 시간이 짧을 때는 처음부터 재생 시간만큼만 재생된다. 조건이 일치하는 음악이 여러 개일 때에는 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환한다. 재생된 시간도 같을 경우 먼저 입력된 음악 제목을 반환한다.

입출력 예시
m : "ABCDEFG"
musicinfos : ["12:00,12:14,HELLO,CDEFGAB", "13:00,13:05,WORLD,ABCDEF"]
-> "HELLO"

function solution(m, musicinfos) {
    var answer = '(None)';
    var ans_length = -1;
    m = convert(m.split(""));
    
    musicinfos.forEach((music) => {
        var [start, end, title, code] = music.split(",");
        var start_min = Number(start.split(":")[0]) * 60 + Number(start.split(":")[1]);
        var end_min = Number(end.split(":")[0]) * 60 + Number(end.split(":")[1]);
        code = convert(code.split(""));
        
        var idx = code.indexOf(m[0]);
        var len = code.length;
        code = (code.slice(idx) + code.slice(0, idx)).slice(0, end_min - start_min);
        idx = code.length;
        while(idx < m.length) {
            code += code[idx % len];
            idx++;
        }
        if (code.includes(m) && ans_length < end_min - start_min) {
            answer = title;
            ans_length = end_min - start_min;
        }
    })
    
    function convert(code, m) {
        var stack = []
        for(var i=0; i<code.length; i++) {
            if (code[i] == '#') {
                var tmp = stack.pop();
                stack.push(tmp.toLowerCase());
            } else {
                stack.push(code[i]);
            }
        }
        return stack.join("")
    }
    return answer;
}

어우 길다...

아 replace로 소문자 변환하는 방법을 모르겠어서 안 썼는데 찾아보니까 사용할 수 있더라. 싱기
그리고 repeat 사용했다가 결과 이상해서 사용 안 했는데 알고 보니까 ceil 안 해줘서 원하는 만큼 repeat 안 된 것...

두 부분 고치면 아래처럼 풀 수도 있었다.
확 줄어듦

function solution(m, musicinfos) {
    var answer = '(None)';
    var ans_length = -1;
    m = m.replace(/[A-Z]#/g, m => m[0].toLowerCase());
    
    musicinfos.forEach((music) => {
        var [start, end, title, code] = music.split(",");
        var start_min = Number(start.split(":")[0]) * 60 + Number(start.split(":")[1]);
        var end_min = Number(end.split(":")[0]) * 60 + Number(end.split(":")[1]);
        code = code.replace(/[A-Z]#/g, c => c[0].toLowerCase());
        
        var idx = code.indexOf(m[0]);
        var len = code.length;
        code = (code.slice(idx) + code.slice(0, idx)).slice(0, end_min - start_min).repeat(Math.ceil(m.length / len));
        if (code.includes(m) && ans_length < end_min - start_min) {
            answer = title;
            ans_length = end_min - start_min;
        }
    })

    return answer;
}

좋은 웹페이지 즐겨찾기