이번 추석에도 시스템 장애가 없는 명절을 보내고 싶은 어피치는 서버를 증설해야 할지 고민이다. 장애 대비용 서버 증설 여부를 결정하기 위해 작년 추석 기간인 9월 15일 로그 데이터를 분석한 후 초당 최대 처리량을 계산해보기로 했다. 초당 최대 처리량은 요청의 응답 완료 여부에 관계없이 임의 시간부터 1초(=1,000밀리초)간 처리하는 요청의 최대 개수를 의미한다.
solution 함수에서는 로그 데이터 lines 배열에 대해 초당 최대 처리량을 리턴한다.
예제1
입력: [
"2016-09-15 01:00:04.001 2.0s",
"2016-09-15 01:00:07.000 2s"
]
출력: 1
예제2
입력: [
"2016-09-15 01:00:04.002 2.0s",
"2016-09-15 01:00:07.000 2s"
]
출력: 2
설명: 처리시간은 시작시간과 끝시간을 포함하므로
첫 번째 로그는 01:00:02.003 ~ 01:00:04.002에서 2초 동안 처리되었으며,
두 번째 로그는 01:00:05.001 ~ 01:00:07.000에서 2초 동안 처리된다.
따라서, 첫 번째 로그가 끝나는 시점과 두 번째 로그가 시작하는 시점의 구간인 01:00:04.002 ~ 01:00:05.001 1초 동안 최대 2개가 된다.
예제3
입력: [
"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"
]
출력: 7
설명: 아래 타임라인 그림에서 빨간색으로 표시된 1초 각 구간의 처리량을 구해보면 (1)은 4개, (2)는 7개, (3)는 2개임을 알 수 있다. 따라서 초당 최대 처리량은 7이 되며, 동일한 최대 처리량을 갖는 1초 구간은 여러 개 존재할 수 있으므로 이 문제에서는 구간이 아닌 개수만 출력한다.
이 전의 풀이는 시간 계산을 좀 멍청하게 했다. 이 전의 내 코드
그냥 단순하게 1번처럼 할 생각을 하지않고 최소한의 연산을 수행하고싶은 마음에 SS.sss가 이전 트래픽에 비해 갑자기 작아질때 boolean값을 true로 놓고 그 이후로는 60000 (60초)를 더해주는 방식으로 했었다.
근데 이 방법이 왜 안되는지는 아직 잘 모른다 ㅜㅜ 솔직히 너무 억지스러워서 마음에 걸리긴 했었는데 논리적으로 작아질 때를 감지해서 end에 60000을 더해줘도 최대 timeout이 3초이기때문에 엉뚱한 트래픽하고 겹치진 않는다고 생각했다.
조금 더 고민을 해봐야겠다!
남들 다 맞는 8번 19번 테케 때문에 적어도 4시간은 고민했다...
코딩테스트를 위해서라도 1시간 이상 고민하면 그냥 답지를 보는게 나은건 알지만 8번 19번 때문에 고생하는 사람은 없어서 일단 데이터가 없었고 무엇보다도 오기가 생겼다.
그래서 좀 찝찝했던 나의 시간 계산법을 수정했더니 바로 됐다.
import java.util.*; class Traffic { int start; int end; Traffic(int start, int end){ this.start = start; this.end = end; } } class Solution { public int solution(String[] lines) { int answer = 0; List<Traffic> t_list = new ArrayList(); for(int i = 0; i < lines.length; i++) { int end =(int)((Integer.parseInt(lines[i].substring(11,13)) * 3600 + Integer.parseInt(lines[i].substring(14,16)) * 60) * 1000 + Double.parseDouble(lines[i].substring(17,23)) * 1000); int treat_time = (int)(Double.parseDouble(lines[i].substring(24, lines[i].length() - 1)) * 1000); int start = end - treat_time + 1; t_list.add(new Traffic(start, end)); } int max = 1; int cnt; for(int i = 0; i < t_list.size(); i++) { cnt = 1; for(int j = i + 1; j < t_list.size(); j++){ if(t_list.get(i).end + 1000 > t_list.get(j).start) cnt++; } if(max < cnt) max = cnt; } answer = max; return answer; } }