코테/lvl2

프로그래머스 방금그곡(lvl2) 풀어보기

디비드킴 2026. 9. 14. 11:47

문제링크

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

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


문제 핵심

-네오는 자신이 기억한 멜로디를 가지고 방금그곡을 이용해 음악을 찾는다. 그런데 라디오 방송에서는 한 음악을 반복해서 재생할 때도 있어서 네오가 기억하고 있는 멜로디는 음악 끝부분과 처음 부분이 이어서 재생된 멜로디일 수도 있다. 반대로, 한 음악을 중간에 끊을 경우 원본 음악에는 네오가 기억한 멜로디가 들어있다 해도 그 곡이 네오가 들은 곡이 아닐 수도 있다. 그렇기 때문에 네오는 기억한 멜로디를 재생 시간과 제공된 악보를 직접 보면서 비교하려고 한다. 다음과 같은 가정을 할 때 네오가 찾으려는 음악의 제목을 구하여라.


문제 풀이법

-#이있을 수 있으니 타겟음악을 음계로 분리

음악묶음 배열을 시간에 맞게 음계로 가공

타겟음악과 일치하는 음계조합이 있는지 체크


코드

 public static String solution(String m, String[] musicinfos) {
        String answer = "";
        List<String> max = new LinkedList<>();
        int index = 0;
        List<String> ml = new LinkedList<>();
        for (int i = 0; i < m.length(); i++) {
            String note = String.valueOf(m.charAt(i));
            if (i + 1 < m.length()
                    && m.charAt(i + 1) == '#') {

                note += "#";
                i++;
            }
            ml.add(note);
        }
        System.out.println("m: " + m);
        for (String mu : musicinfos) {
            String[] mum = mu.split(",");
            LocalTime start = LocalTime.parse(mum[0]);
            LocalTime end = LocalTime.parse(mum[1]);
            int minutes = (int) Duration.between(start, end).toMinutes();
            System.out.println("minutes: " + minutes);
            List<String> arr = new ArrayList<>();
            for (int i = 0; i < mum[3].length(); i++) {

                String note = String.valueOf(mum[3].charAt(i));

                if (i + 1 < mum[3].length()
                        && mum[3].charAt(i + 1) == '#') {

                    note += "#";
                    i++;
                }

                arr.add(note);
            }
            System.out.println(arr);
            int onetimelen = arr.size();
            System.out.println("onetimelen: " + onetimelen);
            String[] melody = new String[minutes];

            if (minutes < onetimelen) {
                for (int i = 0; i < minutes; i++) {
                    melody[i] = arr.get(i);
                }
            } else {
                int mok = minutes / onetimelen;
                System.out.println("mok" + mok);
                int idex = 0;
                for (int i = 0; i < onetimelen * mok; i++) {

                    int num = i % arr.size();

                    melody[i] = arr.get(num);
                    idex += 1;
                }
                if (minutes % onetimelen != 0) {
                    System.out.println("나머지있음");
                    for (int i = 0; i < minutes % onetimelen; i++) {
                        melody[idex] = arr.get(i);
                        idex += 1;
                    }
                }
            }
            System.out.println("melody: " + Arrays.toString(melody));
            for (int i = 0; i <= melody.length - ml.size(); i++) {
                String check = "";

                for (int ii = i; ii < i + ml.size(); ii++) {
                    check = check + melody[ii];
                }
                System.out.println(check);
                if (check.equals(m)) {
                    System.out.println("일치함");
                    if (max.size() != 0) {

                        int oldMinutes = Integer.parseInt(max.get(1));

                        if (oldMinutes < minutes) {

                            System.out.println("더 긴 곡 발견");

                            max.set(0, mum[2]);
                            max.set(1, Integer.toString(minutes));
                            max.set(2, Integer.toString(index));

                        } else if (oldMinutes == minutes
                                && Integer.parseInt(max.get(2)) > index) {

                            System.out.println("더 먼저 나온 곡 발견");

                            max.set(0, mum[2]);
                            max.set(1, Integer.toString(minutes));
                            max.set(2, Integer.toString(index));
                        }

                    } else {

                        max.add(mum[2]);
                        max.add(Integer.toString(minutes));
                        max.add(Integer.toString(index));
                    }
                    break;
                }
            }

            System.out.println("--------------------");
            index += 1;
        }
        if (max.isEmpty()) {
            return "(None)";
        }
        answer = max.get(0);
        System.out.println(answer);
        return answer;
    }

 


결과



gpt피드백

-가장 먼저 줄일 수 있는 건 이 부분이야.

 
if (minutes < onetimelen) {
    ...
} else {
    ...
}
 

사실 melody는 무조건 minutes 길이니까 그냥 처음부터 끝까지 %로 채워도 돼.

 
for (int i = 0; i < minutes; i++) {
    melody[i] = arr.get(i % arr.size());
}
 

그러면 mok, idex, 나머지 처리 전부 없어져.

 

비교하는 부분도 지금은:

 
String check = "";

for (int ii = i; ii < i + ml.size(); ii++) {
    check = check + melody[ii];
}

if (check.equals(m))
 

인데, 이미 ml을 만들어놨으니까 문자열을 다시 만들지 않고 음 단위로 바로 비교하는 게 더 깔끔해.

 
boolean same = true;

for (int j = 0; j < ml.size(); j++) {
    if (!melody[i + j].equals(ml.get(j))) {
        same = false;
        break;
    }
}
 

이 방식이면 "C#" 같은 것도 애초에 음 단위로 비교하니까 코드 의도가 더 분명해.

 
 
 

배운점 느낀점

-그리 어려운 문제는 아니였는데

중간에 #이들어간걸 까먹고 풀어서 

약간 꼬였던 문제였다