[3차] 방금그곡

2020.08.02

const convertTime = (str) => {
  const [hour, minute] = str.split(":");
  const converted = parseInt(hour) * 60 + parseInt(minute);
  return converted;
};

const calculateDuration = (start, end) => {
  const convertedStart = convertTime(start);
  const convertedEnd = convertTime(end);
  return convertedEnd - convertedStart;
};

const substitute = (str) => {
  const stack = [];
  for (let i = 0; i < str.length; i++) {
    const current = str[i];
    if (current == "#") {
      stack.push(stack.pop().toLowerCase());
      continue;
    }
    stack.push(current);
  }
  return stack.join("");
};

const mapHelper = (song, idx) => {
  const [start, end, title, melody] = song.split(",");
  return [calculateDuration(start, end), title, substitute(melody), idx];
};

const repeatMelody = (duration, melody) => {
  if (melody.length >= duration) {
    return melody.slice(0, duration);
  }
  const quotient = Math.floor(duration / melody.length);
  const remainder = duration % melody.length;
  return melody.repeat(quotient) + melody.slice(0, remainder);
};

const sortHelper = (a, b) => {
  if (a[0] > b[0]) {
    return -1;
  }
  if (a[0] < b[0]) {
    return 1;
  }
  if (a[3] > b[3]) {
    return 1;
  }
  return -1;
};
const solution = (m, musicinfos) => {
  const convertedM = substitute(m);
  const filtered = musicinfos
    .map(mapHelper)
    .filter(([duration, title, melody, idx]) => {
      const repeated = repeatMelody(duration, melody);
      if (repeated.includes(convertedM)) {
        return true;
      }
      return false;
    })
    .sort(sortHelper);
  if (filtered.length == 0) {
    return `(None)`;
  }
  return filtered[0][1];
};
  • #붙은 문자를 다른 문자로 치환하는 게 핵심인 것 같다.

  • 다른 사람의 풀이 중 유독 성능이 좋은 코드가 있었다. 마지막 테스트 케이스 2개는 다른 어떤 풀이에서도 실행 시간이 거의 3~4배 가까이 걸렸는데 이분 풀이는 유독 짧게 걸렸다.

const convertTime = (str) => {
  const [hour, minute] = str.split(":");
  const converted = parseInt(hour * 60) + parseInt(minute);
  return converted;
};

const calculateDuration = (start, end) => {
  const convertedStart = convertTime(start);
  const convertedEnd = convertTime(end);
  return convertedEnd - convertedStart;
};

const substitute = (str) => {
  return str
    .replace(/C\#/g, "c")
    .replace(/D\#/g, "d")
    .replace(/F\#/g, "f")
    .replace(/G\#/g, "g")
    .replace(/A\#/g, "a");
};

const mapHelper = (song, idx) => {
  const [start, end, title, melody] = song.split(",");
  return [calculateDuration(start, end), title, substitute(melody), idx];
};

const repeatMelody = (duration, melody) => {
  if (melody.length >= duration) {
    return melody.slice(0, duration);
  }
  const quotient = Math.floor(duration / melody.length);
  const remainder = duration % melody.length;
  return melody.repeat(quotient) + melody.slice(0, remainder);
};

const sortHelper = (a, b) => {
  if (a[0] > b[0]) {
    return -1;
  }
  if (a[0] < b[0]) {
    return 1;
  }
  if (a[3] > b[3]) {
    return 1;
  }
  return -1;
};
const solution = (m, musicinfos) => {
  const convertedM = substitute(m);
  const filtered = musicinfos
    .map(mapHelper)
    .filter(([duration, title, melody, idx]) => {
      const repeated = repeatMelody(duration, melody);
      if (repeated.includes(convertedM)) {
        return true;
      }
      return false;
    })
    .sort(sortHelper);
  if (filtered.length == 0) {
    return `(None)`;
  }
  return filtered[0][1];
};
  • 문자열을 치환하는 함수에서 정규표현식을 쓰니 내 풀이에서도 마지막 두 테스트 케이스의 실행 시간이 현저히 줄었다.
    (그럼에도 전반적인 실행 시간은 그분 풀이보다 오래 걸렸다)

  • 이분 혼자서 정규표현식을 사용한 것도 아닌데 왜 그 풀이가 유독 효율이 좋은걸까

  • map -> filter -> sort/reduce 이렇게 전개하는 로직이 같은데 왜 다른지 ㅠㅠ

  • 그리고 정규표현식도 결국 순회 돌면서 검사하는 거 아닌가 왜 더 효율이 좋지

0개의 댓글