프로그래머스 | 방금그곡 (Java)

mul·2023년 9월 18일
0

코딩테스트연습

목록 보기
49/56

🔒문제

프로그래머스 Lv2. 2018 KAKAO BLIND RECRUITMENT [3차] 방금그곡

🔑해결

네오가 기억한 멜로디 문자열 m과 방송된 곡의 정보를 담고 있는 배열 musicinfos가 주어질 때 네오가 찾으려는 음악의 제목을 구하는 문제이다.

주어진 가정 중에서
1. 멜로디와 악보에 사용되는 음은 C, C#, D, D#, E, F, F#, G, G#, A, A#, B
2. 각 음은 1분에 1개씩 재생
3. 조건이 일치하는 음악이 여러 개일 경우 "재생된 시간"이 제일 긴 음악 제목을 반환, 재생된 시간이 같을 경우 먼저 입력된 음악 제목을 반환
조건을 주의하며 문제를 풀이하였다.

  1. 조건이 일치하는 음악이 여러 개일 경우를 가정하여, 가장 긴 재생 시간을 저장할 max 변수 선언
  2. for문을 통해 musicinfos 배열에 저장된 곡 정보를 확인한다
  3. split 메서드를 사용해 곡정보를 mf 배열에 분리하여 저장
  4. playtime 메서드를 통해 재생 시간 계산
    4-1. 매개변수로 음악의 시작 시간(st)과 끝난 시각(et)을 받아, split으로 시와 분을 분리하여 배열에 저장
    4-2. 시 단위에서 먼저 계산하고, 분 단위로 고쳐 재생된 시간을 계산
  5. playedcode 메서드를 통해 재생된 코드(pc)를 구한다
    5-1. 곡정보에 저장된 악보의 음 갯수(ins)를 구하기 위해 replaceAll메서드를 사용해 "#"을 없앤다
    5-2. pt를 ins로 나눈 몫만큼 for문을 통해 sb에 악보(code)를 append한다
    5-3. pt를 ins로 나눈 나머지만큼 sb에 음을 append한다. append한 음에 #이 붙어있다면 #까지 append한 뒤, 다음 음으로 넘어간다.
  6. pc_contain_m 메서드를 통해 재생된 코드에 m이 포함되는지 확인
    6-1. 재생된 코드(pc)에서 먼저 m의 첫번째 문자와 일치하는 문자를 찾고, 찾았다면 m의 길이만큼 substring하여 잘라낸 string(target)이 m와 같은지 판별한다.
    6-2. 잘라낸 문자 뒤에 #이 존재하면 다른 음이기 때문에 이를 확인하는 작업을 한다
  7. 재생된 코드가 m에 포함 여부를 저장하는 변수 exist가 true이고, 재생 시간(pt)가 max보다 크다면 answer에 제목을 저장한다.

🔓코드

class Solution {
    public String solution(String m, String[] musicinfos) {
        String answer = "(None)";
        
        int max = 0;
        
        for (int i = 0; i < musicinfos.length; i++) {
			String[] mf = musicinfos[i].split(",");
			
			// 재생 시간 계산
			int pt = playtime(mf[0], mf[1]);
			
			// 재생된 코드
			String pc = playedcode(pt, mf[3]);
			
			// 재생된 코드에 m이 포함되는지 확인
			boolean exist = pc_contain_m(pc, m);
			
			// 가장 긴 재생길이인지 확인
			if (exist && pt > max) {
				max = pt;
				answer = mf[2];
			}
		}
        
        return answer;
    }
    
    private boolean pc_contain_m(String pc, String m) {
    	boolean exist = false;
    	
    	for (int i = 0; i <= pc.length() - m.length(); i++) {
			if (pc.charAt(i) == m.charAt(0)) {
				if (i + m.length() < pc.length() && pc.charAt(i+m.length()) == '#') {
					continue;
				}
				String target = pc.substring(i, i+m.length());
				if (target.compareTo(m) == 0) {
					exist = true;
				}
			}
		}
    	
    	return exist;
    }
    
    private String playedcode(int pt, String code) {
    	String pc = "";
    	
    	String notshap = code.replaceAll("#", "");
    	int ins = notshap.length();
    	
    	StringBuilder sb = new StringBuilder();
    	for (int i = 0; i < pt / ins; i++) {
			sb.append(code);
		}
    	
    	int count = 0, i = 0;
    	while (count < pt % ins) {
    		sb.append(code.charAt(i));
    		count++;
    		if(code.charAt(i+1) == '#') {
    			sb.append('#');
    			i++;
    		}
    		i++;
    	}
        
    	pc = sb.toString();
    	
    	return pc;
    }
    
    private int playtime(String st, String et) {
    	int pt = 0;
    	
    	String[] st_arr = st.split(":");
    	String[] et_arr = et.split(":");
    	
    	int h = Integer.parseInt(et_arr[0]) - Integer.parseInt(st_arr[0]);
    	if (h > 0) {
    		pt = h * 60;
    	}
    	pt += Integer.parseInt(et_arr[1]) - Integer.parseInt(st_arr[1]);
    	
    	return pt;
    }
}

0개의 댓글