[프로그래머스][JS]방금그곡
방금그곡
문제
문제: 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()
: 시간을 분으로 변경해 줍니다.- (시간끼리 뺀 값 * 60) + (분끼리 뺀 값)
getFullCode()
: 시간을 이용해서 시간에 맞는 코드를 구합니다.
-tokenizeCode()
'#"을 포함해서 나눠줘야 되기 때문에 문자열보다는 배열로 나눠줍니다.
2-1.fullCode
: 시간에 따라서 맞는 code배열을 반환합니다.
-code.length === time
-time < code.length
-time > code.length
2-2. 이름과,fullCode
로 객체로 만들어 줍니다.
checkCode()
m이 포함되는지 검사하기
내가 들은 기억(m
)은 일부만 들어있어도 안되고 완전체가 다 들어있어야 합니다.
codeLen
:tokenize(m)
으로 m의 코드배열의 길이를 구해줍니다.- 이제 codeLen만큼 check할 코드에서 앞에서부터 slice해서 m과 같은지 검사해주면됩니다.
for (let i = 0; i <= fullCode.length - codeLen; i++) {
if (fullCode.slice(i, i + codeLen).join("") === m) return true;
}
- 배열은 주소값을 비교하기 때문에 문자열로 바꾸어 주어서 m과 직접 비교해줍니다.
- i부터 순회할 때 i뒤의 값이
codeLen
보다 적게 남으면 검사할 필요가 없기 때문에i <= fullCode.length - codeLen
i의 조건을 이렇게 해줍니다.
code
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;
}
마무리
코드가 매우 길다...
처음부터 자세하게 설계하기 보다는 큰 가닥이 그려져서 코딩을 이어갔는데 그것 때문인 것 같다. 설계를 조금 더 디테일하게 하면 구현도 더 빠른시간내에 할 수 있을 것이라 생각된다.
다음부터는 코드 설계를 더 디테일하게 하고 구현해봐야겠다.
Author And Source
이 문제에 관하여([프로그래머스][JS]방금그곡), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@proshy/프로그래머스JS방금그곡저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)