[프로그래머스] 레벨3 (level3) 추석트래픽
2020년 06월 02일, 13:40
추석트래픽
문제설명
이번 추석에도 시스템 장애가 없는 명절을 보내고 싶은 어피치는 서버를 증설해야 할지 고민이다. 장애 대비용 서버 증설 여부를 결정하기 위해 작년 추석 기간인 9월 15일 로그 데이터를 분석한 후 초당 최대 처리량을 계산해보기로 했다. 초당 최대 처리량은 요청의 응답 완료 여부에 관계없이 임의 시간부터 1초(=1,000밀리초)간 처리하는 요청의 최대 개수를 의미한다.
입력 형식
- solution 함수에 전달되는 lines 배열은 N(1 ≦ N ≦ 2,000)개의 로그 문자열로 되어 있으며, 각 로그 문자열마다 요청에 대한 응답완료시간 S와 처리시간 T가 공백으로 구분되어 있다.
- 응답완료시간 S는 작년 추석인 2016년 9월 15일만 포함하여 고정 길이 2016-09-15 hh:mm:ss.sss 형식으로 되어 있다.
- 처리시간 T는 0.1s, 0.312s, 2s 와 같이 최대 소수점 셋째 자리까지 기록하며 뒤에는 초 단위를 의미하는 s로 끝난다.
- 예를 들어, 로그 문자열 2016-09-15 03:10:33.020 0.011s은 2016년 9월 15일 오전 3시 10분 33.010초부터 2016년 9월 15일 오전 3시 10분 33.020초까지 0.011초 동안 처리된 요청을 의미한다. (처리시간은 시작시간과 끝시간을 포함)
- 서버에는 타임아웃이 3초로 적용되어 있기 때문에 처리시간은 0.001 ≦ T ≦ 3.000이다.
- lines 배열은 응답완료시간 S를 기준으로 오름차순 정렬되어 있다.
출력 형식
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초 구간은 여러 개 존재할 수 있으므로 이 문제에서는 구간이 아닌 개수만 출력한다.
문제 설명
레벨3 문제라서 그런지 뭔가 더 어렵게 느껴졌..(그리고 어렵다.)
문제 이해도 힘든편이였다. 그리고 가장 힘들었던 부분은 처리시간에 시작,끝이 포함되는 것이였다.
아직도 사실 잘 이해가 가지 않는다.. 진짜 너무 어렵다..
- Date를 통해 getTime()으로 millsecond를 반환하여
lines를 {start, end}값으로 변환.(어차피 9-15일에 대해서만 계산하니까 값을 줄이기 위해 전역변수 de를 선언해서 빼줌.)
시작시간,끝시간을 포함하니까 start를 구해주는 과정에서 +1을 해줘야함. - start, end를 기준점으로 잡아서 포함되는 line들을 체크.
- 포함되는 시간은 1초를 더하는 것이지만, 시작시간과 끝시간을 포함하니까 +999.
- 포함되는 line들의 수를 count
- start를 기준으로 한 line count의 최댓값 , end를 기준으로 한 line count의 최댓값 중 max값을 answer로 리턴.
const de = new Date("2016-09-14 23:59:57").getTime();
function solution(lines) {
var answer = 0;
let hashs = makeHashArr(lines);
// console.log(hashs)
let starts = hashs.map(e => e.start);
let ends = hashs.map(e => e.end);
let startMax = 0;
let endMax = 0;
ends.forEach(end => {
let count = 0;
hashs.forEach(e => {
if (checkTime(e, end)) {
count++;
}
});
endMax = Math.max(endMax, count);
});
starts.forEach(start => {
let count = 0;
hashs.forEach(e => {
if (checkTime(e, start)) {
count++;
}
});
startMax = Math.max(startMax, count);
});
// console.log(startMax,endMax);
answer = Math.max(startMax, endMax);
return answer;
}
function makeHash(line) {
const splited = line.split(" ");
const date = new Date(`${splited[0]} ${splited[1]}`).getTime() - de;
const execute = parseFloat(splited[2]) * 1000;
return { start: date + 1 - execute, end: date };
}
function makeHashArr(lines) {
return lines.map(e => makeHash(e));
}
function checkTime(hash, time) {
if (hash.start < time && hash.end < time) {
return false;
} else if (hash.start > time + 999 && hash.end > time + 999) {
return false;
}
return true;
}
/*
임의 시간부터 1초
*/
아쉬운 점 || 느낀 점
레벨3부터는 문제 자체도 복잡해지고, 조건들도 더 복잡해지는 것 같다.
이해하는 과정도 힘들고, 이해를 했다고 생각했는데 여러 조건들을 이해를 못해서 틀리는 것 같다.
이런 부분을 갈수록 줄여야하는데 쉽지않다.. ㅠㅠ