function solution(m, musicinfos) {
// #이 들어있는 멜로디는 소문자로 모두 변경
const replaceSharp = (str) => str.replaceAll("A#", "a").replaceAll("G#", "g").replaceAll("F#", "f").replaceAll("D#", "d").replaceAll("C#", "c")
const result = []
m = replaceSharp(m)
for (const musicinfo of musicinfos) {
let [stime, etime, title, info] = musicinfo.split(",")
info = replaceSharp(info)
stime = stime.split(":")
etime = etime.split(":")
let time = (etime[0] - stime[0]) * 60 + (etime[1] - stime[1]) // 총 시간 (h, m 계산)
let cnt = 0
let fulloutput = "" // time만큼 플레이된 악보 정보
while (cnt < time) {
fulloutput += info[cnt % info.length] // 악보 정보 입력
cnt += 1
}
if (fulloutput.includes(m)) result.push([title, time]) // 멜로디 일치할 경우
}
if (result.length) { // 결과가 1개 이상일 때 (1개는 고려하지 않아도 됨)
// 가장 긴 길이의 곡 이름과 시간
let [rname, rtime] = result.sort((a, b) => a[1] - b[1])[result.length - 1]
let rcnt = 0
result.forEach(v => {
if (v[1] === rtime) rcnt += 1
})
// 동일한 길이의 곡이 여러개일 경우 가장 먼저 발견된 곡 이름을 출력
if (rcnt > 1) return result.find((v) => v[1] === rtime)[0]
else return rname
} else {
return "(None)"
}
}
구현 로직
정답을 도출하기는 매우 쉽지만 맞춰줘야할 조건이 몇가지 있습니다.
우선 악보 정보를 플레이된 시간만큼 나열해주어야 합니다. 총 시간(time)을 계산해주기 위해 마지막 h - 시작 h 에 60을 곱한 수와 마지막 m - 시작 m을 합해주면 총 플레이된 분 시간이 나옵니다. 1분에 1음씩 재생된다고 하였으니 time만큼 악보정보를 문자열(fulloutput)로 나열해줍니다. 나열된 문자열에 기억한 멜로디가 포함되어있으면 result 배열에 담아줍니다.
문제는 result에 여러개가 담길 때인데 우선 각 원소의 2번째 요소인 시간을 기준으로 정렬해주고 가장 긴 재생시간의 곡이 여러개일 경우에는 result를 순회해서 해당 재생시간과 일치하는 가장 먼저 발견된 곡 제목을 리턴해줍니다. 그 외의 경우에는 그냥 찾았던 곡 제목(rname)을 리턴하면 됩니다.