프로그래머스 방금 그곡 (level 3)

나의 1차 풀이

function solution(m, musicinfos) {
    var answer = '';
    const arrM = m.split(/(\w\#*)/).filter(x => x.length!==0);
    let max = 0;
    for (let x of musicinfos) {
        let [start, end, title, info] = x.split(",");
        let end_minute = +end.slice(3);
        let start_minute = +start.slice(3);
        let end_hour = +end.slice(0,2);
        let start_hour = +start.slice(0,2);
        let infoCount = 0;
        
        if (+end.slice(3) >= +start.slice(3)) {
            time = 60 * (end_hour - start_hour) + (end_minute - start_minute);
        } else {
            time = 60 * (end_hour - start_hour - 1) + (60 + end_minute - start_minute);
        }
        const arrInfo = info.split(/(\w\#*)/).filter(x => x.length!==0);
        let count = 0;
        for (let i = 0; i < time; i++) {
            if (arrInfo[i % arrInfo.length] === arrM[count % arrM.length]) {
                count++;
            } else {
                infoCount = Math.max(infoCount, count);
                count = 0;
            }
        }
        infoCount = Math.max(infoCount, count);
        
        if (infoCount > max) {
            max = infoCount
            answer = title;
        }
    }
    return answer;
}

musicinfos를 순회하고, 필요한 정보들을 구조 분해 할당으로 받는다. 그 후, info를 순회하면서 가장 많이 패턴이 나온 곡의 제목을 리턴한다.

테스트 케이스 30개 중에 7개를 실패했다. 틀린 원인을 찾아보자..

나의 2차 풀이

function solution(m, musicinfos) {
    var answer = '';
    const arrM = m.split(/(\w\#*)/).filter(x => x.length!==0);
    let max = 0;
    let arr = [];
    for (let x of musicinfos) {
        let [start, end, title, info] = x.split(",");
        let end_minute = +end.slice(3);
        let start_minute = +start.slice(3);
        let end_hour = +end.slice(0,2);
        let start_hour = +start.slice(0,2);
        let infoCount = 0;
        
        if (end_minute >= start_minute) {
            time = 60 * (end_hour - start_hour) + (end_minute - start_minute);
        } else {
            time = 60 * (end_hour - start_hour - 1) + (60 + end_minute - start_minute);
        }
        const arrInfo = info.split(/(\w\#*)/).filter(x => x.length!==0);
        let count = 0;
        for (let i = 0; i < time; i++) {
            if (arrInfo[i % arrInfo.length] === arrM[count % arrM.length]) {
                count++;
                if (count === arrM.length) {
                    arr.push([time, title]);
                    break;
                }
            } else {
                count = 0;
            }
        }
    }
    let timeMax = Math.max(arr.map(x=>x[0]));
    arr = arr.filter(x => x[0] === timeMax);
    return arr.length === 0 ? "(None)" : arr[0][1];
}

규칙을 내가 잘못 이해하고 계속 삽질을 하고 있었다.
패턴이 한번 온전히 나오기만 하면 곡 후보에 드는 것이고, 그 안에서 라디오에서 실행된 길이로 최종 후보를 판별하는 것이었다. 이 방법으로 2개의 테스트 케이스는 해결했지만 아직 5개는 해결되지 않았다..

나의 3차 풀이

function solution(m, musicinfos) {
    var answer = '';
    const arrM = m.split(/(\w\#*)/).filter(x => x.length!==0);
    let max = 0;
    let arr = [];
    for (let x of musicinfos) {
        let [start, end, title, info] = x.split(",");
        let end_minute = +end.slice(3);
        let start_minute = +start.slice(3);
        let end_hour = +end.slice(0,2);
        let start_hour = +start.slice(0,2);
        let infoCount = 0;
        
        if (end_minute >= start_minute) {
            time = 60 * (end_hour - start_hour) + (end_minute - start_minute);
        } else {
            time = 60 * (end_hour - start_hour - 1) + (60 + end_minute - start_minute);
        }
        const arrInfo = info.split(/(\w\#*)/).filter(x => x.length!==0);
        let count = 0;
        for (let i = 0; i < time; i++) {
            if (arrInfo[i % arrInfo.length] === arrM[count % arrM.length]) {
                count++;
                if (count === arrM.length) {
                    arr.push([time, title]);
                    break;
                }
            } else {
                count = 0;
                if (arrInfo[i % arrInfo.length] === arrM[count % arrM.length]) {
                    count++;
                }
            }
        }
    }
    let timeMax = Math.max(...arr.map(x=>+x[0]));
    arr = arr.filter(x => x[0] === timeMax);
    return arr.length === 0 ? "(None)" : arr[0][1];
}

와 정말 허탈하다..
Math.max()를 사용하는 방법을 착각해서 문제를 계속 풀지 못했다. Math.max 안에 배열을 넣는 것이 아니라 배열을 분산시킨 것을 넣어야 한다는 것을 깨달았다. 이전 풀이로 풀린 케이스들은 time의 최댓값을 가지는 악보가 1개여서 가능했다.

나는 사실 문제를 풀면서 약 80퍼센트의 테스트 케이스들이 해결되어서, 내가 놓친 예외 처리가 있는지에 대해서만 계속 고민을 했다. 하지만 한 메서드의 용법을 잘못 알아 통째로 잘못된 알고리즘이었는데도 많은 테스트 케이스들이 맞았다. 메서드 사용할 때 조금 더 신중해보자..

좋은 웹페이지 즐겨찾기