[프로그래머스] 방금 그곡 - javascript

김지원·2022년 2월 10일
1

coding-test

목록 보기
20/25
post-thumbnail
post-custom-banner

📖 문제링크

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

문제 설명

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

👨‍💻 문제풀이

필자가 푼 문제풀이

function solution(m, musicinfos) {
  const result = {};
  let timeout = 0;
  let text = "";
  for (let music of musicinfos) {
    text = "";
    let time = 0;
    let [firstTime, sectime, title, context] = music.split(",");
    let [firstHour, firstMin] = firstTime.split(":");
    let [secHour, secMin] = sectime.split(":");
    timeout = (secHour - firstHour) * 60 + (secMin - firstMin);

    let words = context.split("");
    while (timeout >= time) {
      for (let idx in words) {
        if (time > timeout) break;
        if (words[Number(idx) + 1] === "#") {
          text += words[idx];
          continue;
        }

        text += words[idx];
        ++time;

        if (m.length <= text.length) {
          let textIdx = text.lastIndexOf(m);
          if (textIdx !== -1 && text[textIdx + m.length] !== "#")
            result[title] = timeout;
        }
      }
    }
  }
  const longtime = Math.max.apply(null, Object.values(result));

  if (!Object.keys(result).length) return "(None)";
  return Object.keys(result).find((key) => result[key] === longtime);
}

사실 이 문제의 핵심은 #이 들어간 문자를 다른 문자로 재배치하여 푸는 것이였다.😱
하지만 필자는 #이 있는 그대로 풀었다.

주어진 멜로디의 자리에서 앞에 #이 있다면 추가하고 time을 올리지 않는 식으로 구현하였다.

조건이 일치하는 음악이 여러 개일 때에는 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환한다. 재생된 시간도 같을 경우 먼저 입력된 음악 제목을 반환한다.

그리고 까다로웠던 이 조건은 오브젝트를 이용해 풀었다.

여기서 필자는 30번 테스트가 계속 실패하였었다..

이유는 while문에서 timeout과 멜로디에서 시간을 비교해줬지만 for문안에서는 멜로디의 끝까지 실행시키고 나가기 때문이였다😱

그래서 if문을 추가하였고 모든 테스트가 통과했다.

👨‍💻 재배치했을 때의 코드

function solution(m, musicinfos) {
  m = m
    .replace(/(C#)/g, "c")
    .replace(/(D#)/g, "d")
    .replace(/(F#)/g, "f")
    .replace(/(G#)/g, "g")
    .replace(/(A#)/g, "a");
  const result = {};
  let timeout = 0;
  let text = "";
  for (let music of musicinfos) {
    text = "";
    let time = 0;
    let [firstTime, sectime, title, context] = music.split(",");
    let [firstHour, firstMin] = firstTime.split(":");
    let [secHour, secMin] = sectime.split(":");
    timeout = (secHour - firstHour) * 60 + (secMin - firstMin);
      
    context = context
      .replace(/(C#)/g, "c")
      .replace(/(D#)/g, "d")
      .replace(/(F#)/g, "f")
      .replace(/(G#)/g, "g")
      .replace(/(A#)/g, "a");
      
    let words = context.split("");
    while (timeout >= time) {
      for (let word of words) {
        if (time > timeout) break;
        text += word;
        time++;

        if (m.length <= text.length) {
          let textIdx = text.lastIndexOf(m);
          if (textIdx !== -1) result[title] = timeout;
        }
      }
    }
  }
  const longtime = Math.max.apply(null, Object.values(result));

  if (!Object.keys(result).length) return "(None)";
  return Object.keys(result).find((key) => result[key] === longtime);
}

2022.02.10

profile
backend-developer
post-custom-banner

0개의 댓글