📙 1. 문제
Link : https://school.programmers.co.kr/learn/courses/30/lessons/17683
문제 설명
풀이 1
풀이 과정
1. musininfos를 forEach를 통해 순회하였다. 이 때, 구조분해를 이용하여 startTime(시작 시간), endTime(종료 시간) 등 변수화하였다.
2. C#,D#가 있어서 다음 문자가 #이라면 #과 함께 infoArr 배열에 저장하는 방식으로 하여 #을 묶어서 저장하였다.
3. 2에서 구한 길이와 지속 시간을 이용하여 반복 횟수와 나머지를 구하였다.
4. minusTime 함수를 이용해 시간차를 구한다. minusTime함수는 시간과 분을 분리하여 시간 차이 * 60 + 분 차이를 뺀 결과이다.
5. indexOf를 이용해 m문자가 구한 문자열에 있는지 체크한다.
6. 찾았다면, 찾은 문자 다음에 #이 등장하는 지 체크한 후 #이 있다면 pass하여 다음 index부터 다시구하고, 없다면 answer에 넣어둔다. 이 때, 노래 제목이 2개 이상일 수 있으니 maxTime을 이용해 지속시간이 긴 것이 answer를 업데이트하도록 한다.
7. answer가 업데이트되지 않았다면 노래를 찾지 못한 것이므로 주어진 "(None)"을 return한다.
function solution(m, musicinfos) {
var answer = '';
let maxTime = 0;
// musicinfos를 순회
const minusTime = (startTime,endTime)=>{
const [startHour,startMinute] = startTime.split(':').map(v=>+v)
const startMinutes = startHour*60 + startMinute;
const [endHour,endMinute] = endTime.split(':').map(v=>+v)
const endMinutes = endHour*60 + endMinute;
return endMinutes-startMinutes;
}
musicinfos.forEach(musicinfo=>{
const [startTime,endTime,title,info] = musicinfo.split(',');
const infoArr = [];
// 1. info의 길이 구하기 -> 걍 length하면 안됨 (예외 : C#,D#,F#,G#,A#)
for(let i=0;i<info.length;i++){
if(i===info.length-1) {
infoArr.push(info[i])
continue;
}
if(info[i+1]==='#') {
infoArr.push(info[i]+'#')
i++;
}else{
infoArr.push(info[i])
}
}
// 2. 시간/info길이 만큼 반복
const durationTime = minusTime(startTime,endTime)
const dup = parseInt(durationTime/infoArr.length);
const rest = durationTime%infoArr.length;
let str = ''
for(let i=0;i<dup;i++){
str += info;
}
str += infoArr.slice(0,rest).join('')
let index = str.indexOf(m);
while(index!==-1){
if(str[index+m.length]!=='#'){
if(maxTime<durationTime){
answer=title
maxTime = durationTime
}
break;
}else{
index=str.indexOf(m,index+1)
}
}
})
if(answer==='') return "(None)"
return answer;
}
풀이 2 : 다른 사람 풀이
1. arr배열을 map 메소드를 이용해 musicinfos배열을 수정하여 할당한다.
2. 우선, split(',')을 통해 배열화 시킨후 구조분해 할당한다.
3. 분 = 시간 * 60 + 분임을 이용하여 지속 시간을 구한다.
4. 정규 표현식을 이용하여 음을 구한다
- .match(/[A-Z]#?/g); A-Z(대문자 알파벳)과 #은 있을 수도 있고, 없을 수도 있다.
5. Math.floor을 이용하여 반복횟수를 구한다. -> repeat메소드 이용
6. %를 이용하여 나머지를 구한다.
7. indexOf()를 이용하여 문자열을 포함하고 있는 지 구한다. indexOf()의 두 번째 인자에 i+1을 넣어줌으로써 앞에서부터 검사하며 없다면 다음 것을 탐색한다.
8. [1](runtime)을 기준으로 내림차순 정렬한 다음, 첫 요소를 return하여 runtime이 가장 큰 요소를 반환한다.
풀이 과정
function solution(m, musicinfos) {
const arr = musicinfos.map((mi) => {
const [start, end, title, code] = mi.split(",");
const hour = end.slice(0, 2) - start.slice(0, 2);
const minute = end.slice(3) - start.slice(3);
const runtime = 60 * hour + minute;
const codeArr = code.match(/[A-Z]#?/g);
let stream = code.repeat(Math.floor(runtime / codeArr.length));
stream += codeArr.slice(0,runtime % codeArr.length).join("");
return [title, runtime, stream];
});
const answer = arr.filter(([_, __, stream]) => {
let i = stream.indexOf(m);
if (i === -1) return false;
while (i !== -1) {
if (stream[i + m.length] !== "#") return true;
i = stream.indexOf(m, i + 1);
}
});
if (!answer.length) return "(None)";
answer.sort((a, b) => {
if (a[1] === b[1]) return 0;
return b[1] - a[1];
});
return answer[0][0];
}
🤔 2. 느낀 점
내 이전 코드에서 실수가 나왔다고 처음에 생각하였는데, 전부 맞게 한 풀이었다. 내가 놓쳤던 부분은 indexOf로 찾은 첫 요소의 문자 다음에 #이 오지 않을 경우, 다음 indexOf를 검색해봐야한다는 점이었다. 이 부분을 캐치하지 못하여 자꾸 테스트 입력에 통과하지 못했던 것이다. 다음 번에는 이러한 부분을 꼭 꼼꼼하게 따져보도록 하자.
🤩 3. 한 번 더 짚고 갈 점
1. 문자열.repeat(n) : 문자열을 n만큼 반복
2. 무언가 찾을 때 정규표현식 써버릇 하기(for문 대신에)
3. map, filter함수 애용하기
- 배열을 변환하고 싶다 -> map함수
- 특정한 값을 걸러내고 싶다 -> filter함수
'코딩 테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 표 병합 (0) | 2023.05.21 |
---|---|
[프로그래머스] 코딩테스트 공부 (0) | 2023.05.20 |
[프로그래머스] 표현 가능한 이진트리 (1) | 2023.05.19 |
[프로그래머스] 거리두기 확인하기 (0) | 2023.05.14 |
[프로그래머스] 후보키 (0) | 2023.05.12 |
[프로그래머스] 문자열 압축 (0) | 2023.05.11 |
[프로그래머스] 순위 검색 (0) | 2023.05.07 |
[프로그래머스] 양궁대회 (1) | 2023.04.30 |