akjfal

[Programmers] [3차] 방금 그곡 본문

알고리즘/programmers

[Programmers] [3차] 방금 그곡

akjfal 2021. 6. 22. 23:07
// 제목, 재생시작 종료 시각, 악보
// 1분에 1개씩 재생

// 1. m의 길이를 기준으로한다.
// 2. musicinfos를 라디오 재생시간에 맞게 늘리거나 자른다.
// 3. 늘리거나 줄여진 String에서 m길이만큼 모든 인자를 hashmap에 넣는다.
// 4. 넣으면서 음악의 index를 넣는다.

// C# -> H, D# -> I, F# -> J, G# -> K, A# -> L


import java.util.HashMap;
import java.util.LinkedList;
import java.util.Collections;
import java.util.Iterator;

class Solution {

    class Node{
        int time;
        int idx;
        Node(int time, int idx){
            this.time = time;
            this.idx = idx;
        }
    }
    
    int ansLen;
    HashMap<String, LinkedList<Node>> map;
    
    public String solution(String m, String[] musicinfos) {
        String answer = "(None)";
        m = changeNote(m);
        ansLen = m.length();
        map = new HashMap<>();
        for(int i = 0; i < musicinfos.length; i++){
            fitMusic(musicinfos[i], i);
        }
        if(map.containsKey(m)){
            LinkedList<Node> ansList = map.get(m);
            if(ansList.size() > 1){
                sortList(ansList);
            }
            String[] ansArr = musicinfos[ansList.get(0).idx].split(",");
            answer = ansArr[2];
        }
        return answer;
    }
    
    public void sortList(LinkedList<Node> list){
        Collections.sort(list, (o1, o2) -> {
            if(o1.time > o2.time){
                return -1;
            }else if(o1.time < o2.time){
                return 1;
            }else{
                if(o1.idx < o2.idx)
                    return -1;
                else
                    return 1;
            }
        });
    }
    
    // C# -> H, D# -> I, F# -> J, G# -> K, A# -> L
    public void fitMusic(String radio, int index){
        String[] radioInfo = radio.split(",");
        int totalTime = totalTime(radioInfo[0], radioInfo[1]);
        radioInfo[3] = changeNote(radioInfo[3]);
        int musicLen = radioInfo[3].length();
        int idx = 0;
        if(musicLen > totalTime){
            radioInfo[3] = radioInfo[3].substring(0, totalTime);
        }else if(musicLen < totalTime){
            String basic = radioInfo[3];
            for(int i = 0; i < totalTime/musicLen-1; i++){
                radioInfo[3] += basic;
            }
            radioInfo[3] += radioInfo[3].substring(0, totalTime%musicLen);
        }
        musicLen = radioInfo[3].length();
        // 자르려는 것 보다 길이가 짧을 수 있다.
        for(int i = 0; i < musicLen - ansLen+1; i++){
            String input = radioInfo[3].substring(i, i+ansLen);
            if(map.containsKey(input)){
                map.get(input).add(new Node(totalTime, index));
            }else{
                LinkedList<Node> list = new LinkedList<>();
                list.add(new Node(totalTime, index));
                map.put(input, list);
            }
        }
    }
    
    public int totalTime(String start, String end){
        String[] startTime = start.split(":");
        String[] endTime = end.split(":");
        int startHour = Integer.parseInt(startTime[0]);
        int startMin = Integer.parseInt(startTime[1]);
        int endHour = Integer.parseInt(endTime[0]);
        int endMin = Integer.parseInt(endTime[1]);
        int totalHour = (endHour-startHour) * 60;
        if(startMin > endMin){
            totalHour += 60-startMin + endMin - 60;
        }else{
            totalHour += endMin - startMin;
        }
        return totalHour;
    }
    
    public String changeNote(String note){
        note = note.replaceAll("C#", "H");
        note = note.replaceAll("D#", "I");
        note = note.replaceAll("E#", "M");
        note = note.replaceAll("F#", "J");
        note = note.replaceAll("G#", "K");
        note = note.replaceAll("A#", "L");
        return note;
    }
}

 

HashMap을 이용한 코드다. 덕분에 잘 사용안하는 Collection.sort 람다식을 다시써보게되었다. 하지만 시간, 공간 복잡도, 코드 복잡성 측면에서 indexOf사용한것보다 훨씬 안 좋다.

// 제목, 재생시작 종료 시각, 악보
// 1분에 1개씩 재생

// 1. m의 길이를 기준으로한다.
// 2. musicinfos를 라디오 재생시간에 맞게 늘리거나 자른다.
// 3. indexOf를 통해 포함 여부를 체크하고 maxTime보다 길다면 답을 넣는다.

// C# -> H, D# -> I, F# -> J, G# -> K, A# -> L

class Solution {
    int maxTime;
    String m;
    String answer = "(None)";
    
    public String solution(String m, String[] musicinfos) {
        m = changeNote(m);
        this.m = m;
        for(int i = 0; i < musicinfos.length; i++){
            fitMusic(musicinfos[i], i);
        }
        
        return answer;
    }
    
    // C# -> H, D# -> I, F# -> J, G# -> K, A# -> L
    public void fitMusic(String radio, int index){
        String[] radioInfo = radio.split(",");
        int totalTime = totalTime(radioInfo[0], radioInfo[1]);
        radioInfo[3] = changeNote(radioInfo[3]);
        int musicLen = radioInfo[3].length();
        int idx = 0;
        if(musicLen > totalTime){
            radioInfo[3] = radioInfo[3].substring(0, totalTime);
        }else if(musicLen < totalTime){
            String basic = radioInfo[3];
            for(int i = 0; i < totalTime/musicLen-1; i++){
                radioInfo[3] += basic;
            }
            radioInfo[3] += radioInfo[3].substring(0, totalTime%musicLen);
        }
        System.out.println(radioInfo[3]);
        if(radioInfo[3].indexOf(m) != -1){
            if(totalTime > maxTime){
                maxTime = totalTime;
                answer = radioInfo[2];
            }
        }
    }
    
    public int totalTime(String start, String end){
        String[] startTime = start.split(":");
        String[] endTime = end.split(":");
        int startHour = Integer.parseInt(startTime[0]);
        int startMin = Integer.parseInt(startTime[1]);
        int endHour = Integer.parseInt(endTime[0]);
        int endMin = Integer.parseInt(endTime[1]);
        int totalHour = (endHour-startHour) * 60;
        if(startMin > endMin){
            totalHour += 60-startMin + endMin - 60;
        }else{
            totalHour += endMin - startMin;
        }
        return totalHour;
    }
    
    public String changeNote(String note){
        note = note.replaceAll("C#", "H");
        note = note.replaceAll("D#", "I");
        note = note.replaceAll("E#", "M");
        note = note.replaceAll("F#", "J");
        note = note.replaceAll("G#", "K");
        note = note.replaceAll("A#", "L");
        return note;
    }
}

한결 간단해졌다.

Comments