코딩테스트

방금 그곡

Twisted 2025. 2. 21. 01:45

방금 그곡 풀어보러 가기

 

프로그래머스

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

programmers.co.kr

이번 문제는 2018년 KAKAO BLIND RECRUITMENT에서 나왔던 문제라고 한다.

 

방금 그곡이라는 문제이다.

문제의 내용이나 조건 같은것은 직접한번 살펴보길 바란다. 

 

일단 작성된 전체 코드는 이러하다

public static String solution(String m, String[] musicinfos) {
    String answer = "(None)";
    int maxPlayTime = 0;


    // 기억한 멜로디 변환 (C# -> H 등)
    m = convertSharpNotes(m);

    for (String info : musicinfos) {
        String[] parts = info.split(",");
        String start = parts[0];
        String end = parts[1];
        String title = parts[2];
        String melody = convertSharpNotes(parts[3]);

        // 재생된 시간 계산
        int playTime = getPlayTime(start, end);
        String playedMelody = getPlayedMelody(melody, playTime);

        // 기억한 멜로디 포함 여부 체크
        if (playedMelody.contains(m) && playTime > maxPlayTime) {
            maxPlayTime = playTime;
            answer = title;
        }
    }
    return answer;
}

멜로디와 악보에 사용되는 음들이 영어로 표기되어있고 값들이 각각 C,C#,D,D# .... 이러한 형식으로 되어있다.

 

C#, D# 같은 1개의 값을 처리하고 싶지만 2개의 문자열을 차지하고 있으면 불편한 사항이 많기 때문에 convert메서드를 만들어서 해당 값들은 모두 쓰이지 않는 이후의 영어값들로 치환해주었다.

 

// "#"이 붙은 음을 단일 문자로 변환
private static String convertSharpNotes(String melody) {
    return melody.replace("C#", "H")
            .replace("D#", "I")
            .replace("F#", "J")
            .replace("G#", "K")
            .replace("A#", "L")
            .replace("B#", "M");
}

문제에서는 B#은 나오지 않지만 B#을 넣지 않고 실행했을때 계속해서 실패를 하여 질문하기란을 보았더니 B#이 문제에 누락이란다...

문제에는 안적혀 있지만 꼭 적어야 문제 통과하고 알고리즘 점수 맛있게 먹을 수 있다.

 

musicinfos안에 들어있는 값들은 ["12:00,12:14,HELLO,CDEFGAB","13:00,13:05,WORLD,ABCDEF"]

이런식으로 들있고 각각의 값들은 "시작시간, 종료시간, 노래제목, 악보정보" 를 지칭하고 있다. 

이 값들은 ,(콤마)로 구분되고 있으므로 split메서드를 이용하여 각각의 값들을 구분지어준다.

 

 

이후 각각 재생된 시간을 계산하고, 해당 시간만큼 반복된 멜로디를 생성한다.

// 재생된 시간을 분 단위로 계산
private static int getPlayTime(String start, String end) {
    String[] startParts = start.split(":");
    String[] endParts = end.split(":");
    int startMinutes = Integer.parseInt(startParts[0]) * 60 + Integer.parseInt(startParts[1]);
    int endMinutes = Integer.parseInt(endParts[0]) * 60 + Integer.parseInt(endParts[1]);
    return endMinutes - startMinutes;
}

// 주어진 플레이 시간만큼 멜로디 반복 생성
private static String getPlayedMelody(String melody, int playTime) {
    StringBuilder sb = new StringBuilder();
    int melodyLen = melody.length();

    for (int i = 0; i < playTime; i++) {
        sb.append(melody.charAt(i % melodyLen)); // 멜로디 반복
    }
    return sb.toString();
}

 

이렇게 생성된 멜로디를 반환하여 찾고하자는 멜로디인 m과 일치하는 부분이 있는지를 검사해준다.

// 기억한 멜로디 포함 여부 체크
if (playedMelody.contains(m) && playTime > maxPlayTime) {
    maxPlayTime = playTime;
    answer = title;
}

바로 이부분이다.

노래의 멜로디가 m을 포함하고있고 노래의 재생시간이 최대로 재생된 시간보다 높으면 최대재생시간값을 해당 노래의 재생시간으로 업데이트 해주고 return할 answer에 해당 노래의 제목을 할당해준다.

playTime을 비교해주는 이유는 똑같이 멜로디에 m을 포함하고 있는 경우 플레이시간이 더 긴 노래가 반환되도록 되어있기 때문이다. 

 

개인적인 생각으로 이번 문제는 크게 알고리즘 자체를 평가하는 문제는 아니었던 것 같다.

알고리즘이나 자료구조 보다는 어떻게 접근을 해야할지 생각의 틀이 중요한 문제인 것 같았다.

알고리즘, 자료구조 문제도 좋지만 가끔은 이렇게 발상의 전환이 필요한 문제를 접하는 것도 좋을 것이다.

'코딩테스트' 카테고리의 다른 글

프렌즈 4블록  (0) 2025.02.24
N개의 최소공배수  (0) 2025.02.22
피로도  (0) 2025.02.20
2018 KAKAO BLIND RECRUITMENT [1차 캐시]  (0) 2025.02.18
피보나치 수열(프로그래머스)  (0) 2025.02.17