Seren dev's blog

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;
    }
}

 

해설

카카오 신입 공채 3차 코딩 테스트 문제 해설

 

728x90
profile

Seren dev's blog

@Seren dev

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!