고딩왕 코범석
[프로그래머스] 추석 트래픽, Python3 본문
반응형
입력된 문자열을 시, 분, 초로 파싱하는 것, 각 초 구간의 처리량을 얼마나 효율적으로 분석하냐가 관건인 문제였다.
- 제한사항 및 주의사항
- lines 리스트의 크기는 2,000개 까지다.
- S = 응답 완료 시간, 2016-09-15 hh:mm:ss.sss 형식
- 2016-09-15는 필요 없다.
- T = 처리시간, 0.1s, 2s, 2.0s 등의 형식으로 주어진다.
- 문제에서 나온 예시 처럼 '2016-09-15 03:10:33.020 0.011s'는 03:10:33.010 ~ 03:10:33.020 동안 이뤄진 것이다. 시작시간과 응답 완료 시간을 포함하는 것에 유의하자.
- 시작시간 = S - T + 0.001s
- 풀이전략
- lines를 시작시간, 응답 완료시간으로 분해하자.
- lines[i]를 split하기
- 0번째 : 추석날짜, 1번째 : 응답 완료 시간, 2번째 : 처리 시간
- 2번째인 처리 시간을 소숫점이 있을 경우, 없을 경우를 나눠서 처리해야한다.
- 소숫점이 있는 경우 : split(".")해서 초단위인 s를 제외하기
- 소숫점이 없는 경우 : s를 제외한 문자열을 list로 만든 다음, ["0"]을 추가해주자. 소숫점이 있는 경우처럼 바꿔준다.
- 2번째인 처리 시간을 소숫점이 있을 경우, 없을 경우를 나눠서 처리해야한다.
- 0번째 : 추석날짜, 1번째 : 응답 완료 시간, 2번째 : 처리 시간
- 시간 계산을 위해 datetime 모듈을 사용했다.
- datetime.datetime : 날짜와 시간 정보를 모두 담고 있는 객체이다.
- fromisoformat : 날짜+시간의 iso 포맷의 문자열을 date 타입으로 리턴해준다.
- datetime.timedelta : 밀리세컨즈까지 지원하는 객체이며, date, datetime 타입의 시간연산을 진행할 수 있는 객체이다.
- datetime.datetime : 날짜와 시간 정보를 모두 담고 있는 객체이다.
- 리스트에 [시작 시간, 응답 완료 시간]을 담고 리턴
- lines[i]를 split하기
- 이제 1초간 응답 처리량을 구해보자
- 일단, 모든 구간을 살펴보기에는 2,000(lines의 크기) * 2(시작, 종료시간) * 60(초) * 1,000(millisecond) * 60(분) * 60(시) = 864,000,000,000
이렇게 하지말자 쉬먀 - 우리가 구한 리스트에서 시작시간 ~ 0.999초, 응답 완료 시간 ~ 0.999초 구간 동안 겹치는 트래픽을 찾아 그 최댓값을 반환하면 된다. O(2,000 * 2 * 2,000)
- 1초가 아닌 0.999초의 범위를 설정한 이유는 코드 밑에 설명하겠다.
- 일단, 모든 구간을 살펴보기에는 2,000(lines의 크기) * 2(시작, 종료시간) * 60(초) * 1,000(millisecond) * 60(분) * 60(시) = 864,000,000,000
- lines를 시작시간, 응답 완료시간으로 분해하자.
import datetime
def get_times(lines):
result = []
for line in lines:
data = line.split()
date = str(data[0]) + " " + str(data[1])
if '.' in data[2]:
delay = data[2].split(".")
delay[1] = delay[1][:-1]
else:
delay = list(data[2][:-1])
delay += ['0']
end = datetime.datetime.fromisoformat(date)
start = end - datetime.timedelta(seconds=int(delay[0]), milliseconds=int(delay[1]) - 1)
result.append([start, end])
return result
def compare(point, target):
start = point
end = point + datetime.timedelta(milliseconds=999)
if target[0] <= start <= target[1]:
return True
if target[0] <= end <= target[1]:
return True
if start <= target[0] <= end and start <= target[1] <= end:
return True
# if start <= target[0] <= end:
# return True
# if start <= target[1] <= end:
# return True
# if start <= target[0] <= end and start <= target[1] <= end:
# return True
return False
def solution(lines):
answer = []
times = get_times(lines)
for time in times:
for t in time:
count = 0
for target in times:
if compare(t, target):
count += 1
answer.append(count)
return max(answer)
내가 실수한 곳이 두 군데가 있다.
-
구간 나누기
- 처음에 start + 1초의 범위를 설정했지만 틀렸다. 결국 다른 분들의 코드를 보고 이해할 수 있었다.
- 문제에서 소요시간은 시작시간과 작업 완료 시간을 포함한다.
- start + 0.999초로 구간을 잡아야 문제에서 원하는 기준에 부합하는 범위라고 할 수 있다.
- '작업1'을 기준으로 했을 때, 1초에서 시작했으면 1.999초에 끝난다. 만약 1초~2초였다면 작업2가 해당 범위에 포함되므로 원하는 답을 도출할 수 없다.
- 처음에 start + 1초의 범위를 설정했지만 틀렸다. 결국 다른 분들의 코드를 보고 이해할 수 있었다.
-
시간 비교
- target 안에 start가 있어야 한다.
- target 안에 end가 있어야 한다.
- start와 end 안에 target이 있는 경우
나는 주석처리한 코드를 보면 알 수 있듯 target 시점이 start와 end 안에 있어야 되는 거로 착각해서 테스트 케이스 일부가 틀렸었다.
반응형
'Computer Science > Algorithm' 카테고리의 다른 글
[프로그래머스] 자물쇠와 열쇠, Python3 (0) | 2021.01.28 |
---|---|
[프로그래머스] 가사 검색, Python3 (0) | 2021.01.28 |
[프로그래머스] 동굴 탐험, Python3 (0) | 2021.01.22 |
[프로그래머스] 매칭 점수, Python3 (0) | 2021.01.20 |
[프로그래머스] 징검다리 건너기, Python3 (0) | 2021.01.19 |