문제: https://school.programmers.co.kr/learn/courses/30/lessons/150370
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
사용 알고리즘: 없음 -> 구현
입력
1. today: "yyyy.mm.dd" 형식의 문자열
-> 오늘 날짜
2. terms: ["약관 유효기간", "약관 유효기간", ... ] 문자열 배열
-> 약관 별 유효기간
3. privacies: ["yyyy.mm.dd 약관", "yyyy.mm.dd 약관", ... ] 문자열 배열
-> 수집된 개인 정보의 정보를 담은 배열
오늘 날짜를 확인하고 오늘 날짜 기준 파기해야 할 개인정보의 번호를 리턴해야 한다.
구현 로직
1. 개인정보가 수집된 날짜에 약관의 유효기간을 더함
고려해야 할 경우
- 달에 유효기간을 더했을 때 12가 넘어가는 경우
- 개인정보를 수집한 날이 1일이어서 -1을 했을 때 날짜가 0이 되는 경우
- 12월 1일에 개인정보를 수집하고 유효기간이 1달인 경우
2. 오늘 날짜와 (개인정보를 수집한 날 + 유효기간)을 비교해서 이미 유효기간을 넘긴 파기해야 하는 정보의 번호를 answer 배열에 추가
- 이미 년도가 지난 경우
- 년도는 올해와 같지만 달이 지난 경우
- 년도도 올해와 같고 달도 이번 달이지만 날짜가 지난 경우
먼저 약관의 유효기간을 쉽게 꺼내쓰기 위해 약관과 유효기간으로 분리한 뒤에 dictionary 로 만들었다.
({약관1 : 유효기간1, 약관2 : 유효기간2, ... } -> termsDict[약관] 이런 식으로 약관 별 유효기간을 쉽게 꺼내 쓸 수 있음)
termsDict = {}
# 약관 별 기간 딕셔너리로 만듦
for i in range(len(terms)):
term, period = terms[i].split()
termsDict[term] = period
privacies 도 날과 약관으로 분리 후, 날을 다시 년, 월, 일로 분리하였다. 오늘 날짜인 today 도 년, 월, 일로 분리하였다. (계산이 쉽도록)
privacies 와 today 모두 문자열이기 때문에 계산을 위해 int 형으로 변환해주었다.
# privacies 를 날과 약관으로 나눔
for i in range(len(privacies)):
day, userTerm = privacies[i].split()
# 년, 월, 일로 분리
year, month, date = day.split('.')
todayYear, todayMonth, todayDate = today.split('.')
# int 형으로 변환
year = int(year)
month = int(month)
date = int(date)
todayYear = int(todayYear)
todayMonth = int(todayMonth)
todayDate = int(todayDate)
- 유효기간을 더했을 때 달이 12보다 커지는 경우
개인정보를 수집한 날이 2021년 7월 1일이고 유효기간이 12개월인 경우 -> 7월 + 12개월 = 19월이 되어버림
그렇다면 (19-12)=7월, (2021+1)=2022년으로 계산하면 되지 않을까? (X)
-> 문제에서 유효기간은 1 개월 이상 100 개월 이하라고 되어있기 때문에 단순히 12를 빼주는 것으로는 안됨
year += month // 12
month = month % 12
이렇게 계산해줘야 유효기간이 더 길어지는 경우에도 올바른 값을 계산할 수 있다.
- 개인정보를 수집한 날이 1일이어서 -1 을 했을 때 날짜가 0 이 되는 경우
개인정보를 수집한 날이 2021년 7월 1일이고 유효기간이 12개월인 경우 2022년 6월 28일이 파기할 날짜이다.
그런데 그냥 -1 만 해주면 0 이 되기 때문에 -1 을 했을 때 0 이 되는 경우에는 date 를 28 로 바꾸어주고, month 도 -1 을 해주었다.
(1일의 전 날은 28일이기 때문에 month 도 1을 빼주어야 함)
if date == 0:
date = 28
month -= 1
- 12월 1일에 개인정보를 수집하고 유효기간이 1달인 경우
(나의 겨우 이 케이스를 못 찾아서 한 번 틀렸었다)
개인정보를 수집한 날이 2021년 12월 1일이고 유효기간이 1달인 경우 2021년 12월 28일이 파기해야 할 날짜이다.
하지만 그냥 month 에 유효기간을 더해주고 date 에 -1 을 해주면, (12+1)=13월, (1-1)=0일된다.
13월은 달이 12보다 큰 경우에서 걸림
-> 2021년 + (12월 // 12) 를 해서 2022년이 됨
-> 12월 % 12 = 0월이 됨
0일은 개인정보를 수집한 날이 1일인 경우에서 걸림
-> 0일 -> 28일
그럼 최종적으로 2022년 0월 28일이라는 이상한 파기 날짜가 나오게 된다. 그렇기 때문에 12월 1일에 개인정보를 수집하고 유효기간이 1달인 경우에는 별도의 처리가 필요하다.
month 가 0인 경우 month 를 12 로 바꾸고 년도도 -1 을 해주면 정상적인 값을 얻을 수 있다.
if month == 0:
month = 12
year -= 1
코드 합침
month += int(termsDict[userTerm])
date -= 1
# 유효기간을 더했을 때 달이 12보다 큰 경우
if month > 12:
year += month // 12
month = month % 12
# 개인정보를 수집한 날이 1일인 경우
if date == 0:
date = 28
month -= 1
# 12월 1일에 개인정보를 수집 + 약관의 유효기간이 1달인 경우
if month == 0:
month = 12
year -= 1
이제 오늘 날짜인 today 와 비교해서 파기 기한이 넘긴 privacies 의 번호를 answer 에 추가해줘야 한다.
아래의 3가지 경우를 비교해주면 된다. 인덱스는 0 번부터 시작하기 때문에 i 에 1을 더한 숫자를 answer 에 추가해주었다.
- 이미 년도가 지난 경우
- 년도는 올해와 같지만 달이 지난 경우
- 년도도 올해와 같고 달도 이번 달이지만 날짜가 지난 경우
# 비교
if year < todayYear:
answer.append(i+1)
elif year == todayYear and month < todayMonth:
answer.append(i+1)
elif year == todayYear and month == todayMonth and date < todayDate:
answer.append(i+1)
전체코드
def solution(today, terms, privacies):
termsDict = {}
answer = []
# 약관 별 기간 딕셔너리로 만듦
for i in range(len(terms)):
term, period = terms[i].split()
termsDict[term] = period
# privacies 를 날과 약관으로 나눔
for i in range(len(privacies)):
day, userTerm = privacies[i].split()
year, month, date = day.split('.')
# 날 -> 년, 월, 일로 분리
todayYear, todayMonth, todayDate = today.split('.')
# int 형으로 변환
year = int(year)
month = int(month)
date = int(date)
todayYear = int(todayYear)
todayMonth = int(todayMonth)
todayDate = int(todayDate)
month += int(termsDict[userTerm])
date -= 1
# 유효기간을 더했을 때 달이 12보다 큰 경우
if month > 12:
year += month // 12
month = month % 12
# 개인정보를 수집한 날이 1일인 경우
if date == 0:
date = 28
month -= 1
# 12월 1일에 개인정보를 수집 + 약관의 유효기간이 1달인 경우
if month == 0:
month = 12
year -= 1
# 비교
if year < todayYear:
answer.append(i+1)
elif year == todayYear and month < todayMonth:
answer.append(i+1)
elif year == todayYear and month == todayMonth and date < todayDate:
answer.append(i+1)
return answer
'프로그래머스' 카테고리의 다른 글
[프로그래머스/Python] Lv.2 피로도 (0) | 2024.08.20 |
---|---|
[프로그래머스/Python] 달리기 경주 (0) | 2024.08.13 |
[프로그래머스/python] 2022 KAKAO BLIND RECRUITMENT 주차 요금 계산 (1) | 2024.06.11 |
[프로그래머스/python] 뒤에 있는 큰 수 찾기 (0) | 2024.05.31 |
[프로그래머스/python] 2024 KAKAO WINTER INTERNSHIP가장 많이 받은 선물 (0) | 2024.05.28 |