알고리즘/프로그래머스 카카오

프로그래머스 Lv.4) 추석 트래픽

Zin0_0 2020. 5. 15. 00:00
반응형

카카오 2018 Blind Recruitment

추석 트래픽

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

풀이

결국은 다시 풀어서 맞았다. 전에 문제를 풀었을 때는 확실히 겁에 질렸던 것 같다. 날짜 검사를 해야한다는 압박감에 평소에 쓰지도 않는 Date 라던지 SimpleDateFormat을 검색해서 적용하려고 하고, 그 이후에는 0.001초 마다 검사하면 time over가 뜰텐데 하는 마음에 HashMap에 초단위로 저장을 하고 그랬다. 틀릴줄알고 작성한 코드가 78점이나 나와서 당황했지만, 그게 독이었던 것 같다.

아무튼 문제를 다시 보니까 생각난 풀이는 비교적 간단하다.


for문을 돌면서 하나의 Log마다(이하 Origin) 정보를 받아와서 다시 전체 로그(Target)를 for문을 통해 검사하는 것이다.

1초 안에 검사를 할 수 있는지에 대해서는 Origin이 끝나기 0.001초 전을 기준으로 Target의 수행 시간 사이에 있는지 검사하고

맞으면 카운팅을 해주는 방식이다.

 

1. 편의를 위해 StartTime, EndTime, TaskTime 세 정보를 담은 MyLog 클래스를 만들었다.

2. 파라미터로 주어진 String배열 lines를 돌면서 각각마다 MyLog 객체를 생성해서 ArrayList에 담아주었다.

3. ArrayList를 돌면서 검사 대상이 될 대상 하나씩을 골랐다.

 3-1. 이후 다시 전체 ArrayList를 돌면서 함께 수행할 수 있는지 검사해주었다.

 3-2. 자기 자신도 count를 해야하기 때문에 복잡해질 수 있는 if문을 쓰지 않고, for each를 통해 자기 자신도 검사하게 했다.

4. 3번을 수행한 결과 값을 리턴해줘서 대소비교 후 Max를 갱신했다.

 

 

문제를 잘못 이해해서 시작과 끝을 ms가 없는 ss초에 딱 맞는 구간에서 다음 +1초의 로그를 검사하는 풀이이다.

응답완료시간 S는 작년 추석인 2016년 9월 15일만 포함하여 고정 길이 2016-09-15 hh:mm:ss.sss 형식으로 되어 있다.

이 부분으로 부터 앞의 날짜는 의미가 없다는 판단을 했다. 왜냐하면 완료시간이 2016 09 15이면 어떤 로그가 들어와도 2016 09 15년에 들어왔을 것이기 때문이다. 정말 변태같이 2016 09 14 23:59:59 에 시작해서 2초정도 걸리는 그런 로그가 많은 경우는 없다고 판단했다.

 

1. Spilt을 통해 완료시간 hh:mm:ss.sss와 처리시간 T를 이용했다.

2. 완료 시간과 처리시간을 통해 시작시간, 완료시간을 초단위로 long 변수에 저장했다.

3. 전체 시간은 HashMap을 통해 관리를 하고자 했고, Hour -> Min -> Sec 가 들어있는 전체 Map을 만들어 주었다.

4. 완성된 HashMap을 돌면서 최대 로그를 가지고 있는 초 단위를 구해 답을 return 했다.

 

78점? 정도 나온 것 같다. 나머지 점수는 아마도 예제와 같이 28.3초 ~ 29.3초 이런 식의 TaskTime을 검증하는 답인 것 같다.

저장 방법이랑 판별을 시작하는 시간을 변경해주면 맞을텐데 그게 쉽게 떠오르지 않아서 일단 뒤로 넘겼다..

다시 풀어봐야겠다..

 

코드

import java.util.HashMap;
import java.util.Iterator;

public class ThanksgivingTraffic_17676 {
    public static void main(String[] args) {
        String[] lines = {"2016-09-15 20:59:57.421 0.351s",
                "2016-09-15 20:59:58.233 1.181s",
                "2016-09-15 20:59:58.299 0.8s",
                "2016-09-15 20:59:58.688 1.041s",
                "2016-09-15 20:59:59.591 1.412s",
                "2016-09-15 21:00:00.464 1.466s",
                "2016-09-15 21:00:00.741 1.581s",
                "2016-09-15 21:00:00.748 2.31s",
                "2016-09-15 21:00:00.966 0.381s",
                "2016-09-15 21:00:02.066 2.62s"};
        System.out.println(solution(lines));
    }

    private static int solution(String[] lines) {
        return getMaxTasks(getMap(lines));
    }

    private static int getMaxTasks(HashMap<Integer, HashMap> map) {
        int max =0;
            // 시간 가져오기
        Iterator<Integer> hourIt = map.keySet().iterator();
        while(hourIt.hasNext()) {   // 시간 맵 가져오기
            int hour = hourIt.next();
            HashMap<Integer, HashMap> hourMap = map.get(hour);
            Iterator<Integer> minIt = hourMap.keySet().iterator();
            while(minIt.hasNext()) {    // 분 맵 가져오기
                int min = minIt.next();
                HashMap<Integer, Integer> minMap = hourMap.get(min);
                Iterator<Integer> secKeys = minMap.keySet().iterator();
                while(secKeys.hasNext()) {
                    int sec = secKeys.next();
                    max = Math.max(max, minMap.get(sec));   // task 최대 입력
                    System.out.println(hour + " : " + min + " : " + sec + "  => " + minMap.get(sec));
                }
            }
        }
        return max;
    }

    private static HashMap<Integer, HashMap> getMap(String[] lines) {
        HashMap<Integer, HashMap> resultMap = new HashMap<>();

        for(String line : lines) {
            // 0 : 년월일, 1 : 완료 시간, 2 : 걸린 시간
            String[] infoArr = line.split(" ");
//            setResultMap(getTime(infoArr[1]), getProcessTime(infoArr[2]), resultMap);
        }
        return resultMap;
    }

    private static HashMap<Integer, HashMap> setResultMap(double endTime, double processTime, HashMap<Integer, HashMap> map) {
        double startTime = endTime - processTime;

        for(int i=(int)startTime; i<=(int)endTime; i++) {   //
            addTask(i, map);
//            System.out.println("hour : " + hour + "\t min : " + min + "\t sec : " + sec);
        }
//        addTask((int)endTime,map);
//        System.out.println(map.size());
        return map;
    }

    private static HashMap<Integer, HashMap> addTask(int i, HashMap<Integer, HashMap> map) {
        int hour = i/60/60;
        int min = (i-(hour*60*60))/60;
        int sec = i-(hour*60*60) - min*60;
        HashMap<Integer, HashMap> hourMap;  // key : 분, value : 분 Map
        if(map.containsKey(hour)) { // hour
            hourMap = map.get(hour);    // 전체 맵에서 hour 겟
            HashMap<Integer, Integer> minMap;   // key : 초, value : task 수
            if(hourMap.containsKey(min)) {  // min
                minMap = hourMap.get(min);  // hour에서 min 겟
                if(minMap.containsKey(sec)) {   // sec
                    minMap.replace(sec, minMap.get(sec)+1); // 작업 추가
                } else {    // sec 없음
                    minMap.put(sec, 1); // sec 만들기
                }
                hourMap.replace(min, minMap);   //hour update
            } else {    // min 없음
                minMap = new HashMap<>();
                minMap.put(sec, 1); // min에 sec와 테스크 수 넣고
                hourMap.put(min, minMap);   //hour update
            }
            map.replace(hour, hourMap); // map update
        } else {    // hour 없음
            hourMap = new HashMap<>();
            HashMap<Integer, Integer> minMap = new HashMap<>();    // min Map
            minMap.put(sec, 1);    // min에 sec 추가
            hourMap.put(min, minMap);  // hour에 min 추가
            map.put(hour, hourMap);
        }

        return map;
    }

    /*private static double getTime(String timeStr) {
        double result =0;
        String[] strArr = timeStr.split(":");
        result += Double.parseDouble(strArr[0])*60*60; // 시간을 초로 환산
        result += Double.parseDouble(strArr[1])*60; // 분을 초로 환산
        result += Double.parseDouble(strArr[2]);
        return result;
    }*/

    private static double getProcessTime(String timeStr) {
        return Double.parseDouble(timeStr.replaceAll("s",""));
    }
}

class MyLog {
    String endStr;
    int taskTime;
    long startTime;
    long endTime;

    public MyLog(String endStr, double taskTime) {
        this.endStr = endStr;
        this.taskTime = (int)(taskTime*1000);
        this.endTime = getTime(endStr);
        setStartTime();
    }


    private void setStartTime() {
        this.startTime = endTime - this.taskTime;
    }

    private static long getTime(String timeStr) {
        double result =0;
        String[] strArr = timeStr.split(":");
        result += Double.parseDouble(strArr[0])*60*60; // 시간을 초로 환산
        result += Double.parseDouble(strArr[1])*60; // 분을 초로 환산
        result += Double.parseDouble(strArr[2]);

        return (long)(result*1000);
    }
}
반응형