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 이렇게 전개하는 로직이 같은데 왜 다른지 ㅠㅠ
그리고 정규표현식도 결국 순회 돌면서 검사하는 거 아닌가 왜 더 효율이 좋지