[프로그래머스/17683] [3차] 방금그곡 (Java)

지니·2021년 5월 24일
0

Algorithm_BF

목록 보기
7/7

Question

2018 KAKAO BLIND RECRUITMENT > [3차] 방금그곡

문제 해설

  1. 네오가 기억한 멜로디가 악보에 포함된 노래 제목을 찾아야 함
  2. 라디오에 한 음악을 반복해서 재생 -> 네오가 기억한 멜로디가 음악 끝부분과 첫부분이 이어서 재생된 멜로디일 수 있음
  3. 음악에 중간에 끊길 수 있음 -> 원본 악보 정보에는 있더라고 중간에 끊겼으면 들은 멜로디 아님
  4. 네오가 찾으려는 음악의 제목은?
    1. 네오가 기억한 멜로디와 악보에 사용되는 음은 C, C#, D, D#, E, F, F#, G, G#, A, A#, B 12개
    2. 각 음은 1분에 1개씩 재생
    3. 조건이 일치하는 음악이 없을 때에는 “(None)”을 반환



Solution

풀이 접근 방법

  1. 멜로디 지속 시간 : 시작과 끝나는 시각을 모두 분단위로 변환하여 뺌

    1. 멜로디 지속 시간 > 악보 정보 길이
      1. 초과한 멜로디 지속 시간 만큼 알보 길이 연장
    2. 멜로디 지속 시단 <= 악보 정보 길이
      1. 멜로디 지속 시간 만큼 알보 정보 길이 자름
  2. #이 붙은 음은 다른 음으로 대체

    1. 악보 정보에서 contains 함수로 멜로디를 찾을 때 #을 포함한 음을 판별해낼 수 없음
    2. ex) 악보 정보 : "ABC#" (A, B, C# 음으로 구성되어있음), 멜로디 : "ABC" (A, B, C 음으로 구성되어 있음)
      1. contains 함수는 C# 이라는 음을 하나의 단어로 보지 않고 C와 # 을 따로 구분하기 때문에 멜로디를 포함하는 악보 정보로 판별
    3. # 이 붙은 음들은 C, D, E, F, A, B 이외의 다른 단어로 치환 -> replaceAll 메소드 사용
  3. contains 메소드로 으로 해당 멜로디 포함되는지 확인


정답 코드

class Solution {
    public String solution(String m, String[] musicinfos) {
        int maxPlayTime = -1;
        String answer = "";
        
      	// 멜로디에 들어있는 # 붙은 음 치환
        m = changeMelody(m);
        
        for (String musicInfo : musicinfos) {
            String[] info = musicInfo.split(",");
            String title = info[2];
          	// 악보 정보에 들어있는 # 붙은 음 치환
            String melodyInfo = changeMelody(info[3]);
            
            String[] timeInfo = info[0].split(":");
          	// 시작 시간 분단위로 변환
            int start = Integer.valueOf(timeInfo[0]) * 60 + Integer.valueOf(timeInfo[1]);
            int end = 0;
            
            timeInfo = info[1].split(":");
            // 끝난 시간 분단위로 변환
            end = Integer.valueOf(timeInfo[0]) * 60 + Integer.valueOf(timeInfo[1]);
            
            // 지속 시간 구함
            int play = end - start;
            
            // 음악의 길이보다 재생 지속 시간이 길 때
            if (play > melodyInfo.length()) {
                StringBuilder newMelody = new StringBuilder();
                
                // 나눈 몫 만큼 악보 처음부터 반복
                for (int i = 0; i < play / melodyInfo.length(); i++)
                    newMelody.append(melodyInfo);
                
              	// 나머지만큼 악보에서 잘라서 붙임
                newMelody.append(melodyInfo.substring(0, play % melodyInfo.length()));
                melodyInfo = newMelody.toString();
            } else {
                // 재생 지속 시간 만큼만 재생
                melodyInfo = melodyInfo.substring(0, play);
            }
            
          	// 조건이 일치하는 음악이 여러개면
            // 재생된 시간이 제일 긴 음악 제목을 반환해야 하기 때문에
            // 조건에 멜로디 포함뿐만 아니라, 재생된 시간가지 비교
            if (melodyInfo.contains(m) && play > maxPlayTime) {
                answer = title;
                maxPlayTime = play;
            }
            
        }
        
        return maxPlayTime != -1 ? answer : "(None)";
    }
    
    String changeMelody(String oldMelody) {
        oldMelody = oldMelody.replaceAll("C#", "H");
        oldMelody = oldMelody.replaceAll("D#", "I");
        oldMelody = oldMelody.replaceAll("F#", "J");
        oldMelody = oldMelody.replaceAll("G#", "K");
        String newMelody = oldMelody.replaceAll("A#", "L");
        
        return newMelody;
    }
}

profile
코.빠.죄.아 (코딩에 빠진 게 죄는 아니잖아..!)

0개의 댓글