프로그래머스 Lv.4) 추석 트래픽
카카오 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);
}
}