코딩 테스트/프로그래머스

[프로그래머스] 방금 그곡

2023. 5. 13. 12:47
목차
  1. 📙 1. 문제
  2. 문제 설명
  3. 풀이 1
  4. 풀이 2 : 다른 사람 풀이
  5. 🤔 2. 느낀 점
  6. 🤩 3. 한 번 더 짚고 갈 점

📙 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
  1. 📙 1. 문제
  2. 문제 설명
  3. 풀이 1
  4. 풀이 2 : 다른 사람 풀이
  5. 🤔 2. 느낀 점
  6. 🤩 3. 한 번 더 짚고 갈 점
'코딩 테스트/프로그래머스' 카테고리의 다른 글
  • [프로그래머스] 표현 가능한 이진트리
  • [프로그래머스] 거리두기 확인하기
  • [프로그래머스] 후보키
  • [프로그래머스] 문자열 압축
피터s
피터s
1년차 프론트엔드 개발자입니다 😣 아직 열심히 배우는 중이에요! 리액트를 하고있어요 :) - gueit214@naver.com - https://github.com/gueit214
피터s
피터의 성장기록
피터s
전체
오늘
어제
  • 분류 전체보기 (200)
    • 코딩 테스트 (25)
      • 프로그래머스 (16)
      • LeetCode (8)
      • 백준 (1)
    • 개발 독서 일지 (1)
    • 기업 분석 (4)
    • 개발 일지 (19)
      • 최신기술 도전기 (1)
      • 에러 처리 (5)
      • 개발 일지 (12)
    • 개발 일상 (36)
      • 개발 회고 (22)
      • 개발 이야기 (12)
      • 개발 서적 (1)
    • 취업 관련 지식 (11)
    • 알고리즘 (17)
    • WebProgramming (84)
      • WebProgramming (8)
      • HTML (5)
      • CSS (8)
      • JS (21)
      • React (40)

블로그 메뉴

  • About
  • 2022년 개발 성장기
  • 앞으로의 계획
  • github
  • 일상 blog

공지사항

인기 글

태그

  • 개발 회고
  • 구름
  • lv3
  • 1년 회고
  • KAKAO BLIND
  • 개발 일상
  • 카카오 채용연계형 인턴십
  • 누적합
  • Union-find
  • 반복문
  • 1일 1커밋 후기
  • dfs
  • Kakao Tech Internship
  • Retry
  • LV2
  • 구름톤
  • 스터디 후기
  • 카카오
  • 개발 is life
  • BFS
  • 함수
  • 해커톤

최근 댓글

최근 글

hELLO · Designed By 정상우.
피터s
[프로그래머스] 방금 그곡
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.