[문제 설명]
https://programmers.co.kr/learn/courses/30/lessons/17683
[풀이 과정]
꽤나 많이 삽질하고 해맨 문제다. 여기저기 다른 코드들을 참고하여 풀었다.
문제를 풀면서 포인트라고 생각한 부분들에 대해서 정리를 하겠다.
문제 조건에 다음과 같은 항목이 있다.
1. " 조건이 일치하는 음악이 여러 개일 때에는 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환한다. 재생된 시간도 같을 경우 먼저 입력된 음악 제목을 반환한다. "
정답에 부합하는 답이 여러개일 때 우선순위를 두고 1순위인 답을 반환해야 한다.
답을 모두 구한 뒤에 우선순위를 정하는 것보다 처음에 매개변수로 주어진 리스트를 먼저 정렬한다음, 제일 처음 나온 답을 바로 반환하는 로직으로 구현했다. Comparator 인터페이스를 구현한 클래스를 정의하여 정렬했다.
2. "음악이 00:00를 넘겨서까지 재생되는 일은 없다."
음악의 시작시간과 종료시간으로 "분" 차이를 구하는 메소드를 이용하여 구현했다.
그런데 만약 00:00 시가 종료시간이라면 (종료시간 - 시작시간) 이 음수가 나온다. 따라서 절대값으로 구해줘야 한다.
3. "네오가 기억한 멜로디와 악보에 사용되는 음은 C, C#, D, D#, E, F, F#, G, G#, A, A#, B 12개이다."
음악 재생시간동안 플레이된 멜로디 속에 네오가 기억한 멜로디가 포함되어 있는지 여부를 판별해야 한다.
그런데 #이 참 애매하다. 만약 멜로디 중 "ABC#" 이 있는데 네오가 기억한 멜로디는 "ABC" 라면 실제로는 다른 멜로디인데도 코드에서는 포함된다고 잘못 판별하는 코드를 작성할 수 도 있다.(내가 그랬음)
이번 문제를 풀면서 배운건데, 이렇게 애매한 경우에는 문자열2개짜리를 한개짜리로 바꿔주면 술술 풀린다.
#이 붙은 음들은 모두 소문자 알파벳으로 치환하면 된다.
[JAVA code]
package com.algorithm.level2;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
public class Test38 {
public static void main(String[] args) throws ParseException {
String m = "ABCDEFG";
String[] musicinInfo = {"12:00,12:14,HELLO,CDEFGAB", "13:00,13:05,WORLD,ABCDEF"};
System.out.println(solution(m, musicinInfo));
}
// 플레이 리스트 정렬
// 1. 재생시간이 긴 순서 (내림차순)
// 2. 재싱시간이 같다면 먼저 입력된 순서대로(오름차순)
public static class MusicComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
String[] musicInfo1 = o1.split(",");
String[] musicInfo2 = o2.split(",");
long playTime1 = 0;
long playTime2 = 0;
try {
playTime1 = getPlayTime(musicInfo1[0], musicInfo1[1]);
playTime2 = getPlayTime(musicInfo2[0], musicInfo2[1]);
} catch (ParseException e) {
e.printStackTrace();
}
if (playTime2 > playTime1) {
return 1;
} else if (playTime1 > playTime2) {
return -1;
}
return 1;
}
}
public static String solution(String m, String[] musicinfos) throws ParseException {
MusicComparator musicComparator = new MusicComparator();
Arrays.sort(musicinfos, musicComparator);
for (int i = 0; i < musicinfos.length; i++) {
String[] musicinStr = musicinfos[i].split(",");
long playTime = getPlayTime(musicinStr[0], musicinStr[1]); // 재생시간
String melody = convertMelody(musicinStr[3]); // 멜로디 (#이 붙은 음들은 소문자로 치환)
int count = 0; // 재싱시간만큼 음을 이어붙이는 숫자를 세는 카운트
String resultStr = ""; // 음을 이어붙이는 변수
while (count < playTime) {
for (int j = 0; j < melody.length(); j++) {
if (count == playTime) {
break;
}
resultStr += melody.charAt(j);
count++;
}
}
if (resultStr.contains(convertMelody(m))) {
return musicinStr[2];
}
}
return "(None)";
}
public static long getPlayTime(String startTime, String endTime) throws ParseException {
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
Date d1 = dateFormat.parse(startTime);
Date d2 = dateFormat.parse(endTime);
long diff = Math.abs(d2.getTime() - d1.getTime());
long min = diff / (1000 * 60);
return min;
}
public static String convertMelody(String melody) {
//C, C#, D, D#, E, F, F#, G, G#, A, A#, B
melody = melody.replaceAll("C#", "c");
melody = melody.replaceAll("D#", "d");
melody = melody.replaceAll("F#", "f");
melody = melody.replaceAll("G#", "g");
melody = melody.replaceAll("A#", "a");
return melody;
}
}
'코딩 테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스][Level3][JAVA][단어변환] (0) | 2021.01.09 |
---|---|
[프로그래머스][Level3][2 x n 타일링] (0) | 2020.11.26 |
[프로그래머스][Level2] 압축 - JAVA (0) | 2020.11.20 |
[프로그래머스][Level2][JAVA] 영어 끝말잇기 (0) | 2020.11.07 |
[프로그래머스][Level2][JAVA] 수식 최대화 (0) | 2020.10.24 |