문제

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


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public String solution(String m, String[] musicinfos) {
String answer = "(None)";

m = getSharpReplace(m);

int maxPlayTime = 0;

for (String music : musicinfos) {
String[] info = music.split(",");

int playTimeToMinute = getPlayTime(info[0], info[1]);
String melody = getMelody(playTimeToMinute, info[3]);

if (melody.contains(m)) {
if (maxPlayTime < playTimeToMinute) {
answer = info[2];
maxPlayTime = playTimeToMinute;
}
}
}

return answer;
}

private String getSharpReplace(String arg) {
return arg.replace("C#", "1")
.replace("D#", "2")
.replace("E#", "3")
.replace("F#", "4")
.replace("G#", "5")
.replace("A#", "6");
}

private int getPlayTime(String start, String end) {
LocalTime startTime = convertLocalTime(start);
LocalTime endTime = convertLocalTime(end);

LocalTime playTime = endTime.minusHours(startTime.getHour()).minusMinutes(startTime.getMinute());

return playTime.getHour() * 60 + playTime.getMinute();
}

private LocalTime convertLocalTime(String time) {
String[] hourAndMinute = time.split(":");

return LocalTime.of(Integer.parseInt(hourAndMinute[0]), Integer.parseInt(hourAndMinute[1]), 0);
}

private String getMelody(int playtime, String melody) {
String sharpReplaceMelody = getSharpReplace(melody);
StringBuilder sb = new StringBuilder();

char[] array = sharpReplaceMelody.toCharArray();
for (int i = 0; i < playtime; i++) {
sb.append(array[i % sharpReplaceMelody.length()]);
}

return sb.toString();
}

흐름

  1. “#”이 붙은 음계들을 유일한 값으로 치환한다.
  2. 곡 정보를 담은 musicinfos의 개수만큼 반복한다.
  3. 돌면서 “,”로 잘라 시작시간, 끝난시간, 곡 이름, 멜로디 순으로 구분하여 String array에 저장한다.
  4. 시작 시간과 끝난 시간을 LocalTime type으로 만들어서 끝난 시간에서 시작 시간을 빼서 얼마나 오래 방송 됐는지 playTime을 구한다.
  5. 곡 정보에 있는 멜로디에서도 “#”이 붙은 음계들을 1번에서 한 것과 같은 값으로 치환한다.
  6. playtime에 따라 멜로디에 음계를 추가하기 위해 멜로디를 char array로 변경한다.
  7. playtime 만큼 반복하면서 멜로디를 만든다.
    1. playtime보다 멜로디가 짧은 경우엔 지금 멜로디에 음계를 이어 붙여 playtime 길이 만큼 만든다.
    2. 멜로디가 더 긴 경우엔 playtime 만큼 자른다.
  8. 이렇게 구한 멜로디에 기억 중인 멜로디 m이 포함된다면 playtime이 가장 긴지 확인하고 곡 정보를 저장한다.
  9. 끝.

결과

번호 속도
테스트 1 통과 (1.31ms, 54.1MB)
테스트 2 통과 (1.38ms, 52.7MB)
테스트 3 통과 (3.19ms, 52.6MB)
테스트 4 통과 (1.33ms, 51.7MB)
테스트 5 통과 (1.44ms, 52.7MB)
테스트 6 통과 (1.42ms, 52.2MB)
테스트 7 통과 (2.26ms, 52.7MB)
테스트 8 통과 (2.27ms, 53.3MB)
테스트 9 통과 (2.38ms, 52.5MB)
테스트 10 통과 (2.31ms, 52MB)
테스트 11 통과 (2.24ms, 53.4MB)
테스트 12 통과 (2.03ms, 53.2MB)
테스트 13 통과 (2.27ms, 53.2MB)
테스트 14 통과 (2.23ms, 52.2MB)
테스트 15 통과 (2.19ms, 53.2MB)
테스트 16 통과 (2.22ms, 52.1MB)
테스트 17 통과 (1.78ms, 52.4MB)
테스트 18 통과 (2.22ms, 53MB)
테스트 19 통과 (2.66ms, 52.5MB)
테스트 20 통과 (2.42ms, 52.1MB)
테스트 21 통과 (2.41ms, 52.3MB)
테스트 22 통과 (3.55ms, 52.9MB)
테스트 23 통과 (3.94ms, 53.2MB)
테스트 24 통과 (2.15ms, 51.9MB)
테스트 25 통과 (1.24ms, 52.3MB)
테스트 26 통과 (1.30ms, 53.2MB)
테스트 27 통과 (1.41ms, 52.6MB)
테스트 28 통과 (1.12ms, 53.1MB)
테스트 29 통과 (12.67ms, 53.4MB)
테스트 30 통과 (13.24ms, 53.1MB)

테스트 케이스

1
2
3
4
5
assertEquals("HELLO", test.solution("ABCDEFG", new String[] {"12:00,12:14,HELLO,CDEFGAB", "13:00,13:05,WORLD,ABCDEF"}));
assertEquals("FOO", test.solution("CC#BCC#BCC#BCC#B", new String[] {"03:00,03:30,FOO,CC#B", "04:00,04:08,BAR,CC#BCC#BCC#B"}));
assertEquals("WORLD", test.solution("ABC", new String[] {"12:00,12:14,HELLO,C#DEFGAB", "13:00,13:05,WORLD,ABCDEF"}));
assertEquals("(None)", test.solution("CDEFGAC", new String[] {"12:00,12:06,HELLO,CDEFGA"}));
assertEquals("FOO", test.solution("CCB", new String[] {"03:00,03:10,FOO,CCB#CCB", "04:00,04:08,BAR,ABC"}));