알고리즘/카카오

방금그곡

BSHwan 2019. 9. 8. 16:02
반응형

https://programmers.co.kr/learn/courses/30/lessons/17683

 

코딩테스트 연습 - [3차] 방금그곡 | 프로그래머스

방금그곡 라디오를 자주 듣는 네오는 라디오에서 방금 나왔던 음악이 무슨 음악인지 궁금해질 때가 많다. 그럴 때 네오는 다음 포털의 '방금그곡' 서비스를 이용하곤 한다. 방금그곡에서는 TV, 라디오 등에서 나온 음악에 관해 제목 등의 정보를 제공하는 서비스이다. 네오는 자신이 기억한 멜로디를 가지고 방금그곡을 이용해 음악을 찾는다. 그런데 라디오 방송에서는 한 음악을 반복해서 재생할 때도 있어서 네오가 기억하고 있는 멜로디는 음악 끝부분과 처음 부분이 이어

programmers.co.kr


처음에 생각했던대로 풀었다가 계속 60점이 나와서 뭐가 틀린지 모르는 상태였는데, 같이 알고리즘 스터디를 진행하는 친구한테 힌트를 얻어서 그 부분만 고쳤더니 바로 100점이 나왔던 문제였습니다. 제가 생각했던 부분은 악보정보를 진행되는 시간만큼 반복해서 악보에 내가 찾는 멜로디가 포함되어 있는지 확인하였는데, 그렇게 하면 안됐습니다.

그 이유는 문제에서 멜로디와 악보에서 사용되는 음은 C, C#, D, D#, E, F, F#, G, G#, A, A#, B 이라고 했습니다. 만약에 기억한 멜로디가 ABCD 인데, 악보정보가 ABCD# 이었을 경우를 생각해보겠습니다. 악보정보가 4분동안 재생 되게 된다면 ABCD 이기 때문에 찾는 멜로디가 있다고 판단하고, 그 악보의 제목을 출력했을 것입니다. 하지만 악보정보는 마지막 D#을 하나로 보고 생각해야 되기 때문에, 제가 생각한대로 풀게된다면 예제는 다 맞게되지만 숨겨진 히든케이스에서 틀리게 됩니다. 그래서 A#, C#, D#, F#, G# 을 묶어서 A, C, D, F, G로 바꾸고 알고리즘을 설계하면 정답이 나오게 됩니다.

< 문제 풀이 >

1. 제가 작성한 check 함수는 A# 코드를 a로 바꿔주는 함수입니다. 맨 처음에 주어진 멜로디 m을 check 함수에 넣어줘서 바꿔줍니다. musicinfos 를 처음에 바꿔주어도 되지만, 어차피 반복문으로 처음부터 끝까지 보기 때문에 musicinfos는 그때 바꾸어 줍니다.

2. 주어진 곡의 정보를 "," 로 split 해서 나눠주고, arr 배열에 각 정보를 저장합니다.

3. 시작시간과 끝시간을 문자열로 가져와서 Integer로 형변환을 해주고, 이제 몇분동안 방송되었는지를 나타내는 minutes를 구해야 합니다.

4. 시작시간과 끝시간의 시간의 차를 구하고, 분의 차이를 구해서 시간에는 60(분)을 곱해주고, 분의 차이도 더해주면 시작시간과 끝시간의 차이를 분으로 나타낸 값이 minutes에 저장되게 됩니다.

5. 여기서 악보의 정보를 check 함수로 바꿔줍니다.

6. a 라는 변수에 악보에 사용되는 음의 길이로 minutes 을 나누어 몫을 구하고, b 라는 변수에 나머지를 구해서 저장합니다. a 와 b 는 StringBuilder 로 새로운 문자열을 만드는데, 악보에 사용되는음을 계산된 minutes 만큼 반복되게 해서 저장합니다.

7. 그러면 주어진 시간만큼 반복된 음들이 나왔으므로, 그 음에 우리가 찾는 멜로디가 저장되어 있는지 확인합니다.

8. 여기에서 놓치면 안될것이 있는데, 문제에서 "조건이 일치하는 음악이 여러 개일 때에는 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환한다. 재생된 시간도 같을 경우 먼저 입력된 음악 제목을 반환한다." 라고 나와있습니다. 마지막에 위의 조건을 모두 만족한다면 minutes 을 max 변수를 사용하여 if 문으로 조건을 달아주게 되면, 원하는 정답이 나옵니다.


class Solution {
  	public String solution(String m, String[] musicinfos) {
		String answer = "";
		int max = 0;
		
		m = check(m);
			
		for (int i = 0; i < musicinfos.length; i++) {

			String[] arr = musicinfos[i].split(",");
			String startTime = arr[0];
			String endTime = arr[1];

			String sH = startTime.substring(0, 2);
			String sM = startTime.substring(3, 5);
			String eH = endTime.substring(0, 2);
			String eM = endTime.substring(3, 5);

			int startHour = Integer.parseInt(sH);
			int startMinute = Integer.parseInt(sM);
			int endHour = Integer.parseInt(eH);
			int endMinute = Integer.parseInt(eM);

			int hour = endHour - startHour;
			int minute = endMinute - startMinute;
			int minutes = (hour * 60) + minute;

//	    	  System.out.println(minutes);
			arr[3] = check(arr[3]);
			
			char[] paper = arr[3].toCharArray();
			// 몫
			int a = minutes / paper.length;
			// 나머지
			int b = minutes % paper.length;

			StringBuilder sb = new StringBuilder();

			for (int j = 0; j < a; j++)
				sb.append(arr[3]);
			for (int j = 0; j < b; j++) {
				sb.append(arr[3].charAt(j));
			}

//	    	  System.out.println(sb);

			String target = sb.toString();
			if (target.contains(m)) {
				if (max < minutes) {
					answer = arr[2];
					max = minutes;
				}
			}
		}

		if (answer == "")
			answer = "(None)";

		return answer;
	}

	public static String check(String st) {
		st = st.replaceAll("A#", "a");
		st = st.replaceAll("C#", "c");
		st = st.replaceAll("D#", "d");
		st = st.replaceAll("F#", "f");
		st = st.replaceAll("G#", "g");
		return st;
	}
}
반응형