문제: https://programmers.co.kr/learn/courses/30/lessons/17683#
문제가 길기 때문에 따로 설명은 안하겠습니다. 문제가 궁금하신 분들은 위의 링크를 타고가서 보세요~
musicinfos
에는 시간과 원곡코드가 들어있기 때문에 저희가 필요한용도로 파싱(parser
)해줍니다.
ex) ["12:00,12:04,FOO,A#BC"] => [ {name:FOO, code:[A#,B,C,A#]} ]
만약 둘다 가능할 경우는 재생시간(code.length
)에 비례하기 때문에 정렬해줍니다.
checkCode
: 내 기억(m
)과 parse한 code를 비교해 결과를 도출합니다.
parser()
뮤직인포 파싱하기getTime()
: 시간을 분으로 변경해 줍니다.getFullCode()
: 시간을 이용해서 시간에 맞는 코드를 구합니다.tokenizeCode()
'#"을 포함해서 나눠줘야 되기 때문에 문자열보다는 배열로 나눠줍니다.fullCode
: 시간에 따라서 맞는 code배열을 반환합니다.code.length === time
time < code.length
time > code.length
fullCode
로 객체로 만들어 줍니다.checkCode()
m이 포함되는지 검사하기내가 들은 기억(m
)은 일부만 들어있어도 안되고 완전체가 다 들어있어야 합니다.
codeLen
: tokenize(m)
으로 m의 코드배열의 길이를 구해줍니다.for (let i = 0; i <= fullCode.length - codeLen; i++) {
if (fullCode.slice(i, i + codeLen).join("") === m) return true;
}
codeLen
보다 적게 남으면 검사할 필요가 없기 때문에 i <= fullCode.length - codeLen
i의 조건을 이렇게 해줍니다.function solution(m, musicinfos) {
let musicInfos = parser(musicinfos);
musicInfos.sort((a, b) => b.code.length - a.code.length);
for (let musicInfo of musicInfos) {
if (checkCode(musicInfo.code, m)) {
return musicInfo.name;
}
}
return `(None)`;
}
function parser(musicinfos) {
const newMusicinfos = [];
musicinfos.forEach((musicinfo) => {
const [startTime, endTime, name, code] = musicinfo.split(",");
const time = getTime(startTime, endTime);
const fullCode = getFullCode(time, code);
newMusicinfos.push({ name, code: fullCode });
});
return newMusicinfos;
}
function getTime(start, end) {
start = start.split(":").map((v) => v * 1);
end = end.split(":").map((v) => v * 1);
const hours = end[0] - start[0];
const minutes = end[1] - start[1];
return hours * 60 + minutes;
}
function getFullCode(time, code) {
code = tokenizeCode(code);
let newCode = [];
if (code.length === time) newCode = code;
else if (time < code.length) newCode = code.slice(0, time);
else {
for (let i = 0; i < time; i++) {
newCode.push(code[i % code.length]);
}
}
return newCode;
}
function tokenizeCode(code) {
code = code.split("");
for (let i = 0; i < code.length; i++) {
if (code[i] === "#") {
code[i - 1] += "#";
code.splice(i, 1);
i--;
}
}
return code;
}
function checkCode(fullCode, m) {
const codeLen = tokenizeCode(m).length;
for (let i = 0; i <= fullCode.length - codeLen; i++) {
if (fullCode.slice(i, i + codeLen).join("") === m) return true;
}
return false;
}
코드가 매우 길다...
처음부터 자세하게 설계하기 보다는 큰 가닥이 그려져서 코딩을 이어갔는데 그것 때문인 것 같다. 설계를 조금 더 디테일하게 하면 구현도 더 빠른시간내에 할 수 있을 것이라 생각된다.
다음부터는 코드 설계를 더 디테일하게 하고 구현해봐야겠다.