알고리즘 스터디 2021.07~

[프로그래머스] 2018 카카오 블라인드 - [1차] 추석 트래픽

문제

https://programmers.co.kr/learn/courses/30/lessons/17676

 

코딩테스트 연습 - [1차] 추석 트래픽

입력: [ "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-1

programmers.co.kr


풀이

문제를 이해하는데만 한참 걸렸다.

임의 1초동안 최대 몇 가지의 일을 수행하는지 묻는 문제였다.

주어지는 입력은 "응답완료날짜 응답완료시간 처리시간" 순서로 주어진다.

 

문제가 속하는 알고리즘 카테고리가 명확히 떠오르지 않았다.

그래서 일단 풀이 방법을 냅다 생각해봤다.

 

주어지는 문자열은 응답 완료 시간을 기준으로 순차적으로 주어진다는 점을 힌트로 생각했다.

응답 요청 시간은 제각각이었으므로 완료 시간을 기준으로 연산해야 할 것 같다.

 

  1. 요청 시작 시간을 저장
  2. 하나의 응답 완료 시간을 시작점으로 잡아 그 이후 1초 이내에 처리중인 응답 개수를 저장한다. (연산 시작 시간으로 계산)
  3. 다만 타임아웃 3초 + 문제 요청 1초 = 4초 이후의 응답 완료 시간부터는 연산하지 않는다.
  4. 각 처리 개수 중 가장 큰 값을 반환한다.

 

from datetime import datetime, timedelta

def solution(lines):
    starts = []
    ends = []
    
    for l in lines:
        time = datetime.strptime(l[:23], '%Y-%m-%d %H:%M:%S.%f')
        ends.append(time)
        starts.append(time - timedelta(milliseconds = float(l[24:-1])*1000-1)) #timedelta로 연산. 문제에서 처리시간은 시작과 끝을 포함하였으므로 -1 
    
    maxNum = 0
    for i in range(len(ends)): #각 요청의 응답 완료 시간을 기준으로 최대 처리 개수 계산
        num = 1
        j = i + 1
        while j < len(ends):
            if ends[i] + timedelta(seconds = 4) < ends[j]: #최대 처리시간 3초 + 문제 요구사항 1초
                break
            if starts[j] < ends[i] + timedelta(seconds = 1): #기준 끝점 + 1초 이내에 다른 요청을 처리중일때
                num += 1
            j += 1
        maxNum = maxNum if maxNum > num else num # 최댓값 갱신
    
    return maxNum

파이썬 시간 관련 모듈을 처음 사용해봐서 좀 오래 걸렸다.

time모듈을 사용하다가 연산 관련 기능이 없는 것 같아 datetime 으로 바꾸었다.

datetime.datetime.strptime으로 스트링에서 datetime의 객체로 변환하고 timedelta로 연산 시작 시간을 계산해 저장했다.

 

참고한 문법 자료:

 


다른 사람의 풀이

def solution(lines):

    #get input
    S , E= [], [] 
    totalLines = 0 
    for line in lines:
        totalLines += 1
        type(line)
        (d,s,t) = line.split(" ")

       ##time to float
        t = float(t[0:-1])
        (hh, mm, ss) = s.split(":")
        seconds = float(hh) * 3600 + float(mm) * 60 + float(ss)

        E.append(seconds + 1)
        S.append(seconds - t + 0.001)

    #count the maxTraffic
    S.sort()

    curTraffic = 0
    maxTraffic = 0
    countE = 0
    countS = 0
    while((countE < totalLines) & (countS < totalLines)):
        if(S[countS] < E[countE]):
            curTraffic += 1
            maxTraffic = max(maxTraffic, curTraffic)
            countS += 1
        else: ## it means that a line is over.
            curTraffic -= 1
            countE += 1

    return maxTraffic

시간관련 모듈 안 쓰고 직접 초로 변환해서 계산했다.

나는 day도 처리해줘야 하는 줄 알고 직접 계산하는 방향은 고민도 안 했는데 문제에 9월15일로 고정한다는 말이 있었다..

문제 잘 읽자

마지막 while문의 로직은 잘 이해가 안 간다. 종이 있을 때 다시 봐야겠다.