방법 1) - 연/월/일 비교
def solution(today, terms, privacies):
today = list(map(int, today.split('.'))) # [0]연, [1]월, [2]일
terms = {i[0]: int(i[2:])for i in terms} # 딕셔너리
answer = [] # 파기해야할 정보
for i, pri in enumerate(privacies): # 하나씩 비교
day, kind = pri.split()
day = list(map(int, day.split('.')))
month = terms[kind] # 유효기간
day[1] += month
while day[1] > 12: # 월이 12보다 크면 월-12, 연+1을 계속 반복
day[1] -= 12
day[0] += 1
day[2] -= 1
if day[2] == 0: # 모든 월은 28일까지이므로 0이면 28로 바꿔줌
day[2] = 28
day[1] -= 1
# print(day) # 보관 가능 일자
# 파기해야할 정보
if day[0] < today[0]:
answer.append(i+1)
elif day[0] == today[0] and day[1] < today[1]:
answer.append(i+1)
elif day[0] == today[0] and day[1] == today[1] and day[2] < today[2]:
answer.append(i+1)
return answer
먼저, 주어진 privacies의 요소들을 하나씩 가져와 split()을 이용해 날짜와 약관종류를 분리한다.
그다음으로 날짜를 [연, 월, 일] 형태의 리스트로 만들고 terms에서 해당 약관 종류의 유효기간을 찾는다.
day, kind = pri.split() # 날짜, 약관 종류
day = list(map(int, day.split('.')))
month = terms[kind] # 유효기간
이제 유효기간을 더해 보관 가능 일자 연, 월, 일 구한다.
유효기간이 월 단위이므로 12를 기준으로 판단하여, 파기일자 월인 day[1]이 12보다 크면 -12를 해주고, 연 day[0]에 +1을 해주는 과정을 계속해서 반복한다.
day[1] += month
while day[1] > 12: # 월이 12보다 크면 월-12, 연+1을 계속 반복
day[1] -= 12
day[0] += 1
개인 정보 수집 일자가 2021.05.02일 때 유효기간이 6개월이면 보관 가능 일자는 2021.11.01 임으로 일-1이 되는 것을 알 수 있다.
그러므로 day[2]에 -1을 해준 다음 이 값이 0이면 28로 바꿔주고 월-1을 한다.(문제에서 모든 달은 28일까지 있다고 주어짐)
월-1을 하는 이유는 같은 유효기간에서 개인 정보 수집 일자가 2021.05.01일 때 보관 가능 일자는 2021.10.28이 되는 것을 통해 알 수 있다.
day[2] -= 1
if day[2] == 0: # 모든 월은 28일까지이므로 0이면 28로 바꿔줌
day[2] = 28
day[1] -= 1
이제 보관 가능 일자를 모두 구했으니 오늘 날짜와 비교하여 파기해야 할 정보를 선별한다.
연, 월, 일을 차례대로 비교하여 오늘 날짜가 더 크면 파기목록 answer에 추가한다.
# 파기해야할 정보
if day[0] < today[0]:
answer.append(i+1)
elif day[0] == today[0] and day[1] < today[1]:
answer.append(i+1)
elif day[0] == today[0] and day[1] == today[1] and day[2] < today[2]:
answer.append(i+1)
먼저 연도는 작으면 이미 날짜가 지난 것이므로 쉽게 조건문을 세울 수 있다.
그다음으로 연도가 같을 때 월을 비교하여, 오늘 날짜의 월이 더 크면 보관 가능 일자가 지난 것이므로 파기 목록에 추가하고
연, 월까지 같을 때는 일을 비교하여 지난 날짜이면 파기 목록에 추가하면 된다.
방법 2) - 일 단위로 변환
def solution(today, terms, privacies):
today = list(map(int, today.split('.'))) # [0]연, [1]월, [2]일
terms = {i[0]: int(i[2:])for i in terms}
today = today[0] * 28 * 12 + today[1] * 28 + today[2] # 일 단위로 변환
answer = []
for i, pri in enumerate(privacies):
day, kind = pri.split()
month = terms[kind]
day = list(map(int, day.split('.')))
day = day[0] * 28 * 12 + day[1] * 28 + day[2]-1 + month * 28 # 일 단위로 변환
if day < today:
answer.append(i+1)
return answer
위 방법이 너무나 하드코딩이라 다른 방법을 찾아보니 대부분의 사람들이 이 방식으로 푸는 것을 알게 되었다.
일 단위로 모든 날짜를 변환하여 대소비교를 하는 것이다.
모든 달이 28일까지라고 했으므로 연*28*12 + 월*28 + 일을 통해 날짜를 일 단위로 바꿀 수 있다.
보관 가능 일자 day를 구할 때는 유효기간 month를 일로 바꾼 month*28을 더해준다.
day = day[0] * 28 * 12 + day[1] * 28 + day[2]-1 + month * 28 # 일 단위로 변환
if day < today:
answer.append(i+1)
또한, 위 방법과 같이 일-1, 즉 day[2]-1을 해주어야 정확한 보관 가능 일자를 구할 수 있다.
만약 -1을 하지 않으면 day와 month를 비교하는 조건문에서 등호를 추가해 주어야 답을 구할 수 있다.