ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CodeKata] 프로그래머스: 4.1(목), 방금그곡
    Algorithm 2021. 4. 3. 18:44
    반응형

    🥋 Ooooth!! (Level 2)

    역시 카카오답게 문제가 길다. 우선 musicinfos 의 마지막 요소인 음순서가 음악길이만큼 반복된다. 음악길이는 1,2번째 요소의 시간차이다.

    이렇게 완성된 음악에 m이 포함되는지를 확인해서 음악길이가 가장 긴 음악제목(3번째 요소)를 반환하면 된다. 없으면 "(None)".

     

     🧮 풀이

    function splitMelody(melody) {
      return melody.split("").reduce((acc, cur) => {
        cur = cur === "#" ? acc.pop() + cur : cur;
        return [...acc, cur]
      }, [])
    }
    
    function solution(m, musicinfos) {
      let answer = '';
      let timeMax = 0;
      m = "[" + splitMelody(m).join("][") + "]"
      for (let music of musicinfos) {
        let [start, end, title, melody] = music.split(",");
        const time = (new Date(`1-1 ${end}`) - new Date(`1-1 ${start}`)) / 1000 / 60;
        melody = splitMelody(melody);
        const song = "[" + Array.from({ length: time }, (_,i) => melody[i % melody.length]).join("][") + "]"
    
        if (song.includes(m) && time > timeMax) {
            answer = title;
            timeMax = time;
        }
      }
      return answer ? answer : "(None)";
    }

    1. splitMelody() 함수 만들기

    • 음순서가 string 타입이며, 이를 각 음들로 분할하는 함수이다. 특히, #을 포함하는 반음을 분할하기 위해 조건부 reduce를 적용했다.
    • melody(문자열)을 우선 split() 찢어 배열로 만들고, 이를 다시 배열로 reduce 하되 현재값(cur)이 #이면 누적값(acc) 마지막 값을 pop() 하여 #을 더해주고 다시 넣어준다.

    2. 음악제목 찾기 준비

    • answer는 음악제목을, timeMax는 음악길이를 최신화한다. 두 곡 모두 조건이 일치하면, 길이가 긴 음악을 저장해야되기 때문이다.
    • m을 splitMelody() 함수로 각 음들로 분할한다. 그리고 이를 "[음1][음2]..." 와 같이 구분된 문자열로 join() 한다.
    • 이렇게 한 이유는, ABC#... 에는 ABC가 포함되는 것이 아니지만 원래의 string으로 비교하면 includes()가 true가 나오기 때문이다.

    3. musicinfos 순회하며 음악찾기

    • 각 요소(music)를 split() 하면 [음악시작, 음악끝, 음악제목, 음순서] 로 각 변수에 할당할 수 있다.
    • 먼저, 디지털 타임으로 되어있는 시간값의 차이(time)을 new Date() 메서드로 밀리초로 구한 다음, 값을 나눠 분단위로 변환했다.
    • 음순서(melody) 역시 splitMelody() 로 음으로 나눠준다. 그리고, 이를 time만큼 반복시킨 뒤에 join() 한다.
    • 이 melody에 m이 포함된다면, 그리고 time값이 현재 timeMax 보다 크다면 answer = title, timeMax = time 으로 최신화한다.

     

    🖇 리뷰

    모범답안에 정말 다양한 풀이 케이스가 있다.

    가령, 시간은 ":" 으로 split() 한 다음, 앞에 시간은 * 60, 분은 해당 값으로 빼기를 해주면 time을 구할 수 있다.

    또한, C#, D#과 같은 값들을 H, I, J로 대치한 풀이도 있었다.

     

    하지만, 내가 항상 추구했듯 알고리즘 풀이를 가장 심플하면서도 마치 문제를 그대로 옮겨놓은 것 같은 코드를 구현하고자 하였다.

    반응형
Designed by Tistory.