https://school.programmers.co.kr/learn/courses/30/lessons/17683
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
풀이
멜로디를 포함하는 음악을 찾아야 하며 일치하는 음악이 여러개라면, 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환한다. 재생된 시간도 같을 경우 먼저 입력된 음악 제목을 반환한다.
따라서 정렬을 위해 MusicInfo 자료구조를 생성하였다.
static class MusicInfo implements Comparable<MusicInfo> {
int time;
String title;
String record;
public MusicInfo(int time, String title, String record) {
this.time = time;
this.title = title;
this.record = record;
}
@Override
public int compareTo(MusicInfo o) { // 재생 시간이 긴 순대로 정렬
return o.time - this.time;
}
}
로직
1. 곡의 정보를 담고 있는 배열 musicinfos를 순회하면서, ArrayList<MusicInfo> list에 곡의 정보(재생 시간, 제목, 악보)를 담는다.
2. list를 정렬한다.
3. list를 순회하면서 조건이 일치하는 음악을 찾는다. 재생 시간만큼 재생된 음악의 멜로디를 구하고, 이 음악이 m를 포함하고 있으면 해당 음악의 제목을 리턴한다.
주의할 점
C#, D#, F#, G#, A#은 하나의 음이다. 따라서 악보와 멜로디에 이 음들이 포함되어있으면 각각 c, d, f, g, a로 치환하였다.
코드
import java.util.*;
class Solution {
static class MusicInfo implements Comparable<MusicInfo> {
int time;
String title;
String record;
public MusicInfo(int time, String title, String record) {
this.time = time;
this.title = title;
this.record = record;
}
@Override
public int compareTo(MusicInfo o) { // 재생 시간이 긴 순대로 정렬
return o.time - this.time;
}
}
public String solution(String m, String[] musicinfos) {
ArrayList<MusicInfo> list = new ArrayList<>();
for (String musicinfo: musicinfos) {
String[] infos = musicinfo.split(",");
int time = calculateDiff(infos[0], infos[1]);
list.add(new MusicInfo(time, infos[2], infos[3]));
}
Collections.sort(list);
m = changeSharp(m);
//System.out.println(m);
String answer = "(None)";
for (MusicInfo info: list) {
String music = playMusic(info.time, info.record);
//System.out.println(music);
if (music.contains(m)) {
answer = info.title;
break;
}
}
return answer;
}
static int calculateDiff(String date1, String date2) {
String[] times1 = date1.split(":");
String[] times2 = date2.split(":");
int minutes = Integer.parseInt(times2[1]) - Integer.parseInt(times1[1]);
minutes += 60 * (Integer.parseInt(times2[0]) - Integer.parseInt(times1[0]));
return minutes;
}
static String playMusic(int time, String record) {
//if (time <= 0) return "";
record = changeSharp(record);
StringBuilder music = new StringBuilder();
int cnt = 0;
while (cnt+record.length() <= time) {
music.append(record);
cnt += record.length();
}
if (cnt < time)
music.append(record.substring(0, time-cnt));
return music.toString();
}
static String changeSharp(String str) {
return str.replace("C#", "c")
.replace("D#", "d")
.replace("F#", "f")
.replace("G#", "g")
.replace("A#", "a");
}
}
Arrays.sort()를 사용한 풀이
import java.util.*;
class Solution {
public String solution(String m, String[] musicinfos) {
Arrays.sort(musicinfos, new Comparator<String>(){
@Override
public int compare(String str1, String str2) {
String[] infos1 = str1.split(",");
int time1 = calculateDiff(infos1[0], infos1[1]);
String[] infos2 = str2.split(",");
int time2 = calculateDiff(infos2[0], infos2[1]);
return time2 - time1;
}
});
m = changeSharp(m);
//System.out.println(m);
String answer = "(None)";
for (String info: musicinfos) {
String[] infos = info.split(",");
int time = calculateDiff(infos[0], infos[1]);
String music = playMusic(time, infos[3]);
if (music.contains(m)) {
answer = infos[2];
break;
}
}
return answer;
}
static int calculateDiff(String date1, String date2) {
String[] times1 = date1.split(":");
String[] times2 = date2.split(":");
int minutes = Integer.parseInt(times2[1]) - Integer.parseInt(times1[1]);
minutes += 60 * (Integer.parseInt(times2[0]) - Integer.parseInt(times1[0]));
return minutes;
}
static String playMusic(int time, String record) {
//if (time <= 0) return "";
record = changeSharp(record);
StringBuilder music = new StringBuilder();
int cnt = 0;
while (cnt+record.length() <= time) {
music.append(record);
cnt += record.length();
}
if (cnt < time)
music.append(record.substring(0, time-cnt));
return music.toString();
}
static String changeSharp(String str) {
return str.replace("C#", "c")
.replace("D#", "d")
.replace("F#", "f")
.replace("G#", "g")
.replace("A#", "a");
}
}
다른 풀이
자료구조를 따로 생성해서 List로 정렬할 필요 없이, musicinfos 배열을 한 번만 순회한다.
musicinfos 배열을 순회하면서, 재생 시간이 원래 저장된 시간보다 더 클 때만 음악 제목과 재생 시간을 업데이트한다.
class Solution {
public String solution(String m, String[] musicinfos) {
String answer = "(None)";
int time = 0;
m = edit(m);
for (int inx = 0; inx < musicinfos.length; inx++) {
String[] info = musicinfos[inx].split(",");
int start = (60 * Integer.parseInt(info[0].substring(0, 2)) + Integer.parseInt(info[0].substring(3)));
int end = (60 * Integer.parseInt(info[1].substring(0, 2)) + Integer.parseInt(info[1].substring(3)));
int t = end - start;
if (t > time) {
info[3] = edit(info[3]);
StringBuffer sb = new StringBuffer();
for (int jnx = 0; jnx < t; jnx++) {
sb.append(info[3].charAt(jnx % (info[3].length())));
}
if (sb.toString().indexOf(m) >= 0) {
answer = info[2];
time = t;
}
}
}
return answer;
}
public String edit(String m) {
m = m.replaceAll("C#", "V");
m = m.replaceAll("D#", "W");
m = m.replaceAll("F#", "X");
m = m.replaceAll("G#", "Y");
m = m.replaceAll("A#", "Z");
return m;
}
}
해설
'Algorithm 문제 풀이 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] Lv.2 : 삼각 달팽이 - 자바[Java] (0) | 2024.02.16 |
---|---|
[프로그래머스] Lv.2 : 다리를 지나는 트럭 - 자바[Java] (0) | 2024.02.15 |
[프로그래머스] Lv.2 : [3차] 파일명 정렬 - 자바[Java] (0) | 2023.10.12 |
[프로그래머스] Lv.2 : 오픈채팅방 - 자바[Java] (0) | 2023.10.11 |
[프로그래머스] Lv.1 : 로또의 최고 순위와 최저 순위 - 자바[Java] (0) | 2023.10.01 |