일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 자바 2869
- 팀프로젝트
- 이커머스
- 백준 멀티탭스케줄링 자바
- 백준 1193
- Union Find
- 프로그래머스
- 개발일지
- 조인종류
- 기업분석
- 웹 기술면접
- 1062번 가르침
- 인사관리사이트
- 괄호의값 스택
- 백준 최소비용구하기 자바
- 자바 1193
- 커머스기사
- 백준 2252 자바
- 다익스트라 최소비용구하기
- 백준 1806 자바
- 데이터베이스 기초지식
- 백준 줄세우기 자바
- Spring Security
- 2504 괄호의값 자바
- 백준 괄호의값 자바
- 라이브커머스
- 유니온 파인드
- 온라인쇼핑
- 줄세우기 위상정렬
- 백준 1700 자바
- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 자바 2869
- 팀프로젝트
- 이커머스
- 백준 멀티탭스케줄링 자바
- 백준 1193
- Union Find
- 프로그래머스
- 개발일지
- 조인종류
- 기업분석
- 웹 기술면접
- 1062번 가르침
- 인사관리사이트
- 괄호의값 스택
- 백준 최소비용구하기 자바
- 자바 1193
- 커머스기사
- 백준 2252 자바
- 다익스트라 최소비용구하기
- 백준 1806 자바
- 데이터베이스 기초지식
- 백준 줄세우기 자바
- Spring Security
- 2504 괄호의값 자바
- 백준 괄호의값 자바
- 라이브커머스
- 유니온 파인드
- 온라인쇼핑
- 줄세우기 위상정렬
- 백준 1700 자바
- Today
- Total
JumpUp
프로그래머스 [방금그곡] 본문
2018 KAKAO BLIND RECURITMENT [3차] 문제
[N진수 게임], [파일명 정렬], [압축]은 어렵지 않게 풀었는데 [방금그곡]문제는 다른 사람의 풀이를 보고서야 모든 테스트케이스를 통과할 수 있었다. 보니까 다른 문제들은 정답률이 대개 90%가 넘는 거에 비해 이 문제는 40%대 였다. 수정 전 풀이과정에서 놓친 부분들을 다시 살펴보면서 수정 한 코드를 다시 리뷰해보겠다.
수정 전
<풀이과정>
1. 입력 데이터 정제
A# => a, B# => b 처럼 음을 비교하기 쉽게 바꿈. //sheetMusic()를 만들어 이 과정을 수행함.
musicinfos {음악 시작 기각, 음악 끝난 시각, 음악 제목, 악보} => musicinfos {재싱시간, 음악제목, 악보}로 원하는 데이터로 입력 데이터를 바꿈.
2. 재생시간이 악보 길이보다 길면,재싱시간만큼 음악을 반복시킴
짧다면, 재싱시간만큼 악보를 자름.
3. 조건에 부합하는 musicinfo들의 인덱스를 리스트에 추가함.
4. 리스트의 크기가 2 이상이라면, 가장 긴 재생시간을 가진 음악 제목을 반환.
크기가 1이라면, 조건에 부합하는 음악제목을 반환.
그것도 아니라면, "(None)"을 반환.
이 과정에서 제대로 구현하지 못한 것들을 빨간색으로 표시하였다.
첫째, A# => a, B# => b 처럼 음을 비교하기 쉽게 바꿈.
1, 2차 시도 시에는 이 과정마저 고려하지 않았다. 그러다 보니 악보에 네오가 기억한 멜로디가 포함되는지 확인하는 과정에서 문제가 발생한다.
예)
네오가 기억한 멜로디 : ABC
악보 : ABC#
contain()메소드로 확인하면, true로 반환된다. 같은 멜로디가 아님에도 불구하고.
그렇기에 C#이 같은 하나의 음으로 인식될 수 있도록 C# => c로 바꾸는 과정이 필요한 것이다.
둘째, 재싱시간만큼 음악을 반복시킴
예) ABc으로 이루어진 악보가 10분간 재생된다 하자.
재생시간만큼 음악을 반복시킨다 하면,
ABcABcABcA 로 악보가 이루어져야 한다.
하지만, 내가 구현한 코드대로 한다면
ABcABcABc 로 악보가 이루어진다.
셋째, 가장 긴 재생시간을 가진 음악 제목을 반환.
조건에 부합하는 음악이 여러 개라면, 가장 긴 재생시간을 가진 음악 제목을 반환하고, 가장 긴 재생시간을 가진 음악도 여러개라면 가장 먼저 입력된 음악제목을 반환해야 한다.
하지만, "가장 긴 재생시간을 가진 음악도 여러개라면 가장 먼저 입력된 음악제목을 반환해야 한다." 이 부분을 고려하지 못한 코드로 구현하였다.
import java.util.*;
public class 방금그곡 {
public static String solution(String m, String[] musicinfos) {
m = sheetMusic(m);
int playingTime , hour, min = 0;
String sound = "";
List<Integer> select = new ArrayList<>();
for(int i=0;i<musicinfos.length;i++){
sound = musicinfos[i].split(",")[3];
musicinfos[i] = musicinfos[i].replace(sound, sheetMusic(sound));
sound = musicinfos[i].split(",")[3];
hour = Integer.parseInt(musicinfos[i].split(",")[1].split(":")[0]) - Integer.parseInt(musicinfos[i].split(",")[0].split(":")[0]);
min = Integer.parseInt(musicinfos[i].split(",")[1].split(":")[1]) - Integer.parseInt(musicinfos[i].split(",")[0].split(":")[1]);
playingTime = hour*60 + min;
musicinfos[i] = musicinfos[i].replace(musicinfos[i].split(",")[0]+","+musicinfos[i].split(",")[1], Integer.toString(playingTime));
if(sound.length() < playingTime){
for(int j=0;j<playingTime/sound.length()-1;j++){
musicinfos[i] += sound;
}
}else{
musicinfos[i] = musicinfos[i].replace(sound, sound.substring(0,playingTime));
}
if(musicinfos[i].split(",")[2].contains(m)) {
select.add(i);
}
}
int time, longPlayingTime = 0;
String answer = "";
if(select.size() > 1){
longPlayingTime = Integer.parseInt(musicinfos[select.get(0)].split(",")[0]);
for(int i=1;i<select.size();i++){
time = Integer.parseInt(musicinfos[select.get(i)].split(",")[0]);
if(Integer.parseInt(musicinfos[select.get(i)].split(",")[0]) == Math.max(longPlayingTime,Integer.parseInt(musicinfos[select.get(i)].split(",")[0]))){
longPlayingTime = Integer.parseInt(musicinfos[select.get(i)].split(",")[0]);
answer = musicinfos[select.get(i)].split(",")[1];
}else{
answer = musicinfos[select.get(0)].split(",")[1];
}
}
}else if(select.size() == 1){
answer = musicinfos[select.get(0)].split(",")[1];
}else{
answer = "(None)";
}
return answer;
}
public static String sheetMusic(String sound){
for(int i=0;i<sound.length();i++){
if(sound.charAt(i) == '#') sound = sound.replaceFirst("[A-G]#",sound.substring(i-1,i).toLowerCase());
}
return sound;
}
}
수정 후
reference : hongjuzzang.github.io/solution/code_p17683/
[java] 프로그래머스 - 방금그곡
프로그래머스 - 방금그곡 문제풀이
hongjuzzang.github.io
다른 분이 풀이한 과정을 보니, 내가 어떤 부분들을 놓쳤는지 알게 되었고 바로 수정을 해보았다.
<수정 전 후 비교 풀이과정>
1. 필요한 요소들을 Info 클래스로 만들었다.
조건에 부합한 가장 긴 음악시간이 여러 개 일 경우, 가장 먼저 입력된 음악 제목을 반환하기 위해 필요한
musicinfo의 인덱스를 저장할 index와
재생시간, 음악 제목, 재생시간에 맞춰 가공한 악보로 이루어졌다.
2. 재생시간보다 악보의 길이가 같거나 길어질 때까지 음악을 반복시킨다(=악보를 이어 붙인다)
그러고 나서, 재생시간만큼 악보를 잘라낸다.
3. getMelody(), getPlayingTime(), getTotalMelody()와같이 기능을 분리해 메서드를 생성했다.
그러고 나니 코드 가독성도 solution() 메서드의 의도도 쉽게 파악할 수 있게 되었다.
/*
*reference : https://hongjuzzang.github.io/solution/code_p17683/
*/
import java.util.*;
public class 방금그곡 {
public static void main(String[] args) {
방금그곡 test = new 방금그곡();
System.out.println(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"}));
}
public String solution(String m, String[] musicinfos) {
m = getMelody(m);
int playingTime = 0;
String melody = "";
List<Info> selected = new ArrayList<>();
for(int i=0;i<musicinfos.length;i++){
String[] t = musicinfos[i].split(",");
Info info = new Info(i, getPlayingTime(t[0], t[1]), t[2], getMelody(t[3]));
if (info.totalMelody.length() >= m.length() && info.totalMelody.contains(m))
selected.add(info);
}
String answer = "";
if(selected.size() > 1){
selected.sort((o1, o2) -> {
if(o1.playingTime == o2.playingTime){
return o1.index - o2.index;
}else return o2.playingTime - o1.playingTime;
});
answer = selected.get(0).music;
}else if(selected.size() == 1){
answer = selected.get(0).music;
}else{
answer = "(None)";
}
return answer;
}
public String getMelody(String melody){
for(int i=0;i<melody.length();i++){
if(melody.charAt(i) == '#') melody = melody.replaceFirst("[A-G]#",melody.substring(i-1,i).toLowerCase());
}
return melody;
}
public int getPlayingTime(String start, String finish){
int hour = Integer.parseInt(finish.split(":")[0]) - Integer.parseInt(start.split(":")[0]);
int min = Integer.parseInt(finish.split(":")[1]) - Integer.parseInt(start.split(":")[1]);
return hour*60 + min;
}
class Info{
private int index;
private int playingTime;
private String music;
private String totalMelody;
public Info(int index, int playingTime, String music, String melody){
this.index = index;
this.playingTime = playingTime;
this.music = music;
totalMelody = getTotalMelody(melody, playingTime);
}
public String getTotalMelody(String melody, int playingTime){
if (melody.length() > playingTime)
return melody.substring(0, playingTime);
StringBuilder sb = new StringBuilder();
while (sb.length() < playingTime) {
sb.append(melody);
}
return sb.substring(0, playingTime);
}
}
}
'알고리즘' 카테고리의 다른 글
프로그래머스 [다음 큰 숫자] (0) | 2021.06.01 |
---|---|
프로그래머스 [후보키] (0) | 2021.04.26 |
프로그래머스 [완주하지 못한 선수] (0) | 2021.04.05 |
프로그래머스 [신규 아이디 추천] (0) | 2021.04.05 |
프로그래머스 [폰켓몬] (0) | 2021.04.02 |