[Programmers] 추석 트래픽

김상현·2022년 5월 12일
0

알고리즘

목록 보기
108/301
post-thumbnail

[Programmers] 추석 트래픽

📍 문제 설명

이번 추석에도 시스템 장애가 없는 명절을 보내고 싶은 어피치는 서버를 증설해야 할지 고민이다. 장애 대비용 서버 증설 여부를 결정하기 위해 작년 추석 기간인 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 형식으로 되어 있다.
  • 처리시간 T0.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초 구간은 여러 개 존재할 수 있으므로 이 문제에서는 구간이 아닌 개수만 출력한다.


📍 풀이 및 코드

✍ 풀이

  • 트래픽이 시작하고 종료되는 시간을 초단위로 변경하여 [트래픽 시작 시간, 트래픽 종료 시간] 형식으로 저장
  • 각 트래픽 마다 <트래픽 시작 시간 - 1초 ~ 트래픽 시작 시간> 구간과 <트래픽 종료 시간 ~ 트래픽 종료 시간 + 1초> 구간에서 겹치는 트래픽의 수를 계산한 후 가장 많은 트래픽의 수를 answer 에 갱신한다.

✍ 코드

def solution(lines):
    answer = 1
    report = [] # [[ 트래픽별 시작 시간, 종료 시간 ], ... ]
    
    for line in lines:
        h, m, s = line.split()[1].split(':')
        T = round(float(line.split()[2][:-1]) - 0.001,3)
        end = 3600 * float(h) + 60 * float(m) + float(s) # 트래픽 종료 시간 : 시간, 분의 단위를 모두 초 단위로 변환
        start = round(end - T,3) # 트래픽 시작 시간
        report.append([start,end])
        
    for i in range(len(lines)):
        [start, end] = report[i]
        oneStart = round(start - 0.999,3) # 트래픽 시작 1초 전
        oneEnd = round(end + 0.999,3) # 트래픽 종료 1초 후
        fCount = 0 # 시작점을 기준으로 1초 구간에 걸치는 트래픽의 수
        bCount = 0 # 종료점을 기준으로 1초 구간에 걸치는 트래픽의 수
        for j in range(len(lines)):
            if (oneStart <= report[j][0] <= start) or (oneStart <= report[j][1] <= start) or ((report[j][0] <= oneStart) and report[j][1] >= start):
                fCount += 1
            if (oneEnd <= report[j][0] <= end) or (oneEnd <= report[j][1] <= end) or ((report[j][0] <= oneEnd) and report[j][1] >= end):
                bCount += 1
        answer = max(answer, fCount, bCount)
    return answer
profile
목적 있는 글쓰기

0개의 댓글