728x90
반응형
https://programmers.co.kr/learn/courses/30/lessons/17683
이 문제의 핵심 고려 내용
- 방금그곡 서비스에서는 음악 제목, 재생이 시작되고 끝난 시각, 악보를 제공한다.
- 네오가 기억한 멜로디와 악보에 사용되는 음은 C, C#, D, D#, E, F, F#, G, G#, A, A#, B 12개이다.
- 각 음은 1분에 1개씩 재생된다. 음악은 반드시 처음부터 재생되며 음악 길이보다 재생된 시간이 길 때는 음악이 끊김 없이 처음부터 반복해서 재생된다. 음악 길이보다 재생된 시간이 짧을 때는 처음부터 재생 시간만큼만 재생된다.
- 음악이 00:00를 넘겨서까지 재생되는 일은 없다.
- 조건이 일치하는 음악이 여러 개일 때에는 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환한다. 재생된 시간도 같을 경우 먼저 입력된 음악 제목을 반환한다.
- 조건이 일치하는 음악이 없을 때에는 “(None)”을 반환한다.
입출력 예시
m | musicinfos | answer |
"ABCDEFG" | ["12:00,12:14,HELLO,CDEFGAB", "13:00,13:05,WORLD,ABCDEF"] | "HELLO" |
"CC#BCC#BCC#BCC#B" | ["03:00,03:30,FOO,CC#B", "04:00,04:08,BAR,CC#BCC#BCC#B"] | "FOO" |
"ABC" | ["12:00,12:14,HELLO,C#DEFGAB", "13:00,13:05,WORLD,ABCDEF"] | "WORLD" |
두 번째 고려해야할 내용에서 #이 붙은 것은 다른 문자로 치환을 해줘야 한다.
EX) C# => Z
public String replaceString(String s) {
return s.replaceAll("A#", "V").replaceAll("C#", "W").replaceAll("D#", "X").replaceAll("F#", "Y").replaceAll("G#", "Z");
}
세 번째 고려해야할 내용에서 음악시간보다 재생시간이 더 긴 경우, 이어서 해당 곡을 재생해서 재생시간만큼 붙여야 한다.
EX)
첫 번째 예시에서 HELLO는 길이가 7분이지만 12:00부터 12:14까지 재생되었으므로 실제로 CDEFGABCDEFGAB로 재생되었고, 이 중에 기억한 멜로디인 ABCDEFG가 들어있다.
세 번째 예시에서 HELLO는 C#DEFGABC#DEFGAB로, WORLD는 ABCDE로 재생되었다.
세 번째 예시에서는 WORLD가 제목인 노래의 재생 시간은 5분이다. 길이가 5이므로 ABCDE까지 재생되는 것이 맞다.
// 시(Hour) 단위의 시간 차이를 구한다.
int sH = Integer.parseInt(start[0]);
int eH = Integer.parseInt(end[0]);
int diff = (eH - sH) * 60;
// 분(Minute) 단위의 시간 차이를 구한다.
int sM = Integer.parseInt(start[1]);
int eM = Integer.parseInt(end[1]);
int minute = (eM + diff) - sM;
song.time = minute;
// 전체 문자열을 구하는 변수
String total = "";
// 몫을 구한다. 전체 분 / 노래의 시간
int div = minute / contents.length();
// 몫 만큼 노래 음악을 더한다.
for (int j = 0; j < div; j++) {
total += contents;
}
// 노래가 저장되었고, 나누어떨어지지 않으면
if(!"".equals(total) && minute % contents.length() != 0) total += contents.substring(0, minute % contents.length());
// 노래가 저장되지 않았다면 재생시간만큼 음악을 더해준다.
if("".equals(total)) total = contents.substring(0, minute);
다섯 번째와 여섯 번째 고려해야할 사항은
기억한 내용이 음악에 포함되면 음악의 제목을 반환해야한다.
단, 똑같이 포함되는 케이스들이 있다면 재생시간이 더 긴 제목을 반환해야하고,
재생시간마저 똑같다면 먼저 입력된 노래를 반환한다.
int maxTime = Integer.MIN_VALUE;
String maxTitle = "";
for (int i = 0; i < list.size(); i++) {
Song song = list.get(i);
if(song.lylics.contains(m)) {
if(maxTime < song.time) {
maxTitle = song.title;
maxTime = Math.max(maxTime, song.time);
}
}
}
if(!"".equals(maxTitle)) return maxTitle;
return "(None)";
전체 소스는 아래와 같다.
package implementation.justNowThatSong;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class JustNowThatSong {
public static void main(String[] args) {
Solution s1 = new Solution();
String m1 = "ABCDEFG";
String[] arr1 = {"12:00,12:14,HELLO,CDEFGAB", "13:00,13:05,WORLD,ABCDEF"};
System.out.println(s1.solution(m1, arr1));
Solution s2 = new Solution();
String m2 = "CC#BCC#BCC#BCC#B";
String[] arr2 = {"03:00,03:30,FOO,CC#B", "04:00,04:08,BAR,CC#BCC#BCC#B"};
System.out.println(s2.solution(m2, arr2));
Solution s3 = new Solution();
String m3 = "ABC";
String[] arr3 = {"12:00,12:14,HELLO,C#DEFGAB", "13:00,13:05,WORLD,ABCDEF"};
System.out.println(s3.solution(m3, arr3));
}
}
class Solution {
// # 붙은건 다른 문자로 바꾸기
// A# => V
// C# => W
// D# => X
// F# => Y
// G# => Z
public String solution(String m, String[] musicinfos) {
List<Song> list = new ArrayList<Song>();
m = replaceString(m);
for (int i = 0; i < musicinfos.length; i++) {
String[] musicInfo = musicinfos[i].split(",");
String[] start = musicInfo[0].split(":");
String[] end = musicInfo[1].split(":");
Song song = new Song();
String title = musicInfo[2];
String contents = replaceString(musicInfo[3]);
song.title = title;
int sH = Integer.parseInt(start[0]);
int eH = Integer.parseInt(end[0]);
int diff = (eH - sH) * 60;
int sM = Integer.parseInt(start[1]);
int eM = Integer.parseInt(end[1]);
int minute = (eM + diff) - sM;
song.time = minute;
String total = "";
int div = minute / contents.length();
for (int j = 0; j < div; j++) {
total += contents;
}
if(!"".equals(total) && minute % contents.length() != 0) total += contents.substring(0, minute % contents.length());
if("".equals(total)) total = contents.substring(0, minute);
song.lylics = total;
list.add(song);
}
int maxTime = Integer.MIN_VALUE;
String maxTitle = "";
for (int i = 0; i < list.size(); i++) {
Song song = list.get(i);
if(song.lylics.contains(m)) {
if(maxTime < song.time) {
maxTitle = song.title;
maxTime = Math.max(maxTime, song.time);
}
}
}
if(!"".equals(maxTitle)) return maxTitle;
return "(None)";
}
public String replaceString(String s) {
return s.replaceAll("A#", "V").replaceAll("C#", "W").replaceAll("D#", "X").replaceAll("F#", "Y").replaceAll("G#", "Z");
}
}
class Song {
int time;
String title;
String lylics;
}
728x90
반응형
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스/java] 피로도 (0) | 2022.08.11 |
---|---|
[프로그래머스/Oracle] 우유와 요거트가 담긴 장바구니 (0) | 2022.08.07 |
[프로그래머스/java] 오픈채팅방 - 2019 KAKAO BLIND RECRUITMENT - 리스트(List)를 배열(Array)로 (0) | 2022.04.05 |
[프로그래머스/sql] 헤비 유저가 소유한 장소 - ORACLE 셀프조인 (0) | 2022.04.01 |
[프로그래머스/java] 모음사전 - 재귀를 이용하여 푸는 문제 (0) | 2022.04.01 |
댓글