https://programmers.co.kr/learn/courses/30/lessons/17683
// 각음은 1분씩재생,
// 음악길이보다 재생된 시간이 길때는 음악이 끊김없이 처음부터 반복해서 재생됨..
// 음악길이보다 재생된 시간이 짧을 때는 처음부터 재생
// 음악이 00:00를 넘겨서까지 재생되는 일은 없음
// 조건일치하는 음악이 여러개면 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환.
// 재생된 시간도 같으면 먼저 입력된 제목 반환
// 없으면 None반환
// [시작시간 , 끝 시간, 음악제목, 악보정보 ]
// 1: replace를 사용해서 뒤에 샾이 들어가는 문자를 소문자로 치환해 준다 (주의: A#과 C#의 소문자는 a,c이런식으로 다르게 해야함)
// 2: 시간차이를 구해준다 여러 방법이 있다 (이건 생각해 보시길...) exam)13:50, 14:20 = 30
// 3:시간의 차이만큼 반복적으로 음이 나오도록 while문을 돌린다 그리고 그 값을 변수에 저장한다
// 4:그 '변수문자열'에 기억하는 '음문자열'이 들어있느지 확인해본다 (이 기술은 생각해 보시길... 쉬움...)
// 5: 만약에 있다면 해쉬를 사용하여 {music: 노래이름, 길이: 아까구한 시간차이}배열에 푸쉬한다
// 6:배열에 길이(key)를 이용하여 내림차순으로 정렬한뒤
// 7: 만약 길이가 0이면 (None)를 리턴 아니면 배열의[0].music을 리턴 한다
// 사용된 악보 C, C#, D, D#, E, F, F#, G, G#, A, A#, B
function solution(m, musicinfos) {
m = m.replace(/(C#)/g, 'c').replace(/(D#)/g, 'd').replace(/(F#)/g, 'f').replace(/(G#)/g, 'g').replace(/(A#)/g, 'a');
// console.log(m)
musicinfos = musicinfos.map(el => el.split(','))
changeCode(musicinfos); // 1
let timeGap = getTimeGap(musicinfos); // 2
let codeArr = makeCode(timeGap, musicinfos); // 3
let musicList = makeMusicList(m, codeArr, timeGap, musicinfos);
let sortedList = sortList(musicList);
// console.log(sortedList);
// console.log(codeArr);
// console.log(timeGap);
let answer = sortedList.length==0 ? '(None)' : sortedList[0][0];
return answer;
}
function sortList(musicList) {
let tmp = [];
for (let k in musicList) {
tmp.push([k, musicList[k]])
}
tmp.sort((a, b) => {
return b[1] - a[1];
})
return tmp;
}
function makeMusicList(m, codeArr, timeGap, musicinfos) {
let musicList = {}
for (let i = 0; i < codeArr.length; i++) {
let code = codeArr[i];
let idx = code.indexOf(m);
if (idx != -1) musicList[musicinfos[i][2]] = timeGap[i];
}
return musicList;
}
function makeCode(timeGap, musicinfos) {
let makeCode = [];
for (let i = 0; i < timeGap.length; i++) {
let tmp = '';
let code = musicinfos[i][3];
for (let j = 0; j < timeGap[i]; j++) {
tmp += code[j % musicinfos[i][3].length];
}
makeCode.push(tmp);
}
return makeCode;
}
function changeCode(musicinfos) {
for (let i = 0; i < musicinfos.length; i++) {
let tmp = musicinfos[i].pop();
tmp = tmp.replace(/(C#)/g, 'c').replace(/(D#)/g, 'd').replace(/(F#)/g, 'f').replace(/(G#)/g, 'g').replace(/(A#)/g, 'a');
musicinfos[i].push(tmp);
}
}
function getTimeGap(musicinfos) {
let tGap = [];
for (let i = 0; i < musicinfos.length; i++) {
let t1 = musicinfos[i][0].split(':');
let t2 = musicinfos[i][1].split(':');
let timeGap = Math.abs((t1[0] - t2[0]) * 60 + (t1[1] - t2[1]));
tGap.push(timeGap);
}
return tGap;
}
let m = "CC#BCC#BCC#BCC#B";
let musicinfos = ["03:00,03:30,FOO,CC#B", "04:00,04:08,BAR,CC#BCC#BCC#B"];
console.log(solution(m, musicinfos));
문제 조건
각 음은 1분씩재생,
음악길이보다 재생된 시간이 길때는 음악이 끊김없이 처음부터 반복해서 재생됨..
음악길이보다 재생된 시간이 짧을 때는 처음부터 재생
음악이 00:00를 넘겨서까지 재생되는 일은 없음
조건일치하는 음악이 여러개면 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환.
재생된 시간도 같으면 먼저 입력된 제목 반환
없으면 None반환
musicinfos : [시작시간 , 끝 시간, 음악제목, 악보정보 ]
이 문제는 그냥 구현하는 문제인 듯 하다.
처음에 문제 이해가 잘안되서 질문게시판에 풀이 꿀팁을 참고했다.
과정은 아래와 같다.
- replace를 사용해서 뒤에 샾이 들어가는 문자를 소문자로 치환해 준다
(주의: A#과 C#의 소문자는 a,c이런식으로 다르게 해야함)- 시간차이를 구해준다 여러 방법이 있다 (이건 생각해 보시길...) exam)13:50, 14:20 = 30
- 시간의 차이만큼 반복적으로 음이 나오도록 while문을 돌린다 그리고 그 값을 변수에 저장한다
- 그 '변수문자열'에 기억하는 '음문자열'이 들어있느지 확인해본다 (이 기술은 생각해 보시길... 쉬움...)
- 만약에 있다면 해쉬를 사용하여 {music: 노래이름, 길이: 아까구한 시간차이}배열에 푸쉬한다
- 배열에 길이(key)를 이용하여 내림차순으로 정렬한뒤
- 만약 길이가 0이면 (None)를 리턴 아니면 배열의[0].music을 리턴 한다
! 사용된 악보 C, C#, D, D#, E, F, F#, G, G#, A, A#, B
위 과정대로 구현했더니 통과되었다.
그럼 과정을 살펴보자.
처음부터 문자열 끝까지 돌면서 #붙을때마다 바꿔줘야하나 했는데 문제 설명에 사용된 악보종류가 나와있어서 해당 종류만 replace하는 것으로 바꿧다.
문제에 나오는 네오가 자주듣는 코드 m과 musicinfos에 있는 코드들에서 #을 제거해준다.
m = m.replace(/(C#)/g, 'c').replace(/(D#)/g, 'd').replace(/(F#)/g, 'f').replace(/(G#)/g, 'g').replace(/(A#)/g, 'a');
...
function changeCode(musicinfos) {
for (let i = 0; i < musicinfos.length; i++) {
let tmp = musicinfos[i].pop();
tmp = tmp.replace(/(C#)/g, 'c').replace(/(D#)/g, 'd').replace(/(F#)/g, 'f').replace(/(G#)/g, 'g').replace(/(A#)/g, 'a');
musicinfos[i].push(tmp);
}
}
musicinfos에 있는 시작 시간과 끝 시간의 차이를 구하기 위한 getTimeGap메소드이다.
각 시간부분을 split으로 나누어 시간끼리 뺀것에 60을 곱하여 단위는 분으로 잡았다. 그리고 분끼리 뺀것을 합친 문자열을 배열에 저장해 리턴한다.
function getTimeGap(musicinfos) {
let tGap = [];
for (let i = 0; i < musicinfos.length; i++) {
let t1 = musicinfos[i][0].split(':');
let t2 = musicinfos[i][1].split(':');
let timeGap = Math.abs((t1[0] - t2[0]) * 60 + (t1[1] - t2[1]));
tGap.push(timeGap);
}
return tGap;
}
시간차이 만큼 코드를 반복한 문자열을 만드는 makeCode()메소드다.
function makeCode(timeGap, musicinfos) {
let makeCode = [];
for (let i = 0; i < timeGap.length; i++) {
let tmp = '';
let code = musicinfos[i][3];
for (let j = 0; j < timeGap[i]; j++) {
tmp += code[j % musicinfos[i][3].length];
}
makeCode.push(tmp);
}
return makeCode;
}
네오가 기억하는 코드 m이 만들어낸 코드에 들어있는지 찾아야 한다.
function makeMusicList(m, codeArr, timeGap, musicinfos) {
let musicList = {}
for (let i = 0; i < codeArr.length; i++) {
let code = codeArr[i];
let idx = code.indexOf(m);
if (idx != -1) musicList[musicinfos[i][2]] = timeGap[i];
}
return musicList;
}
indexOf로 m이 -1이 아닌경우에 해당 노래의 제목을 key로 하고, 시간차이를 value로 가지는 객체를 리턴한다.
[key, value] 배열로 임의의 tmp배열에 넣어두고 tmp를 value기준으로 정렬하여 리턴한다.
function sortList(musicList) {
let tmp = [];
for (let k in musicList) {
tmp.push([k, musicList[k]])
}
tmp.sort((a, b) => {
return b[1] - a[1];
})
return tmp;
}
만약 정렬된 배열길이가 0이라면 '(None)' 을 리턴하고, 아니라면 가장 첫번째의 노래 제목을 리턴한다.
let answer = sortedList.length==0 ? '(None)' : sortedList[0][0];