문제 요약
https://school.programmers.co.kr/learn/courses/30/lessons/150370
1. today(오늘의 날짜), terms(약관 종류 별 유효기간), privacies(개인정보 수집일자와 약관 종류)가 문자열로 주어짐
2. 약관 별 유효기간은 1달에서 100달
3. 날짜는 2000<=YYYY<=2022, 1<=MM<=12, 1<=DD<=28 로 제한
privacies에서 개인정보 수집일자 + 유효 기간 < 오늘 날짜 를 만족하는 인덱스를 반환한다.
접근
만만하게 보고 그냥 문제 조건만 따라가며 코드를 짰다.
하지만 엄청난 삽질을 하게 되는데...
월 → 년 계산
1. 더해야 하는 유효 기간이 100달까지인 것을 간과해서 이런 바보같은 코드를 짰다.
if m + term > 12:
y += 1
m += term - 12
else:
m += term
2. 12월로 나눠서 계산 → 또 틀림
year_cnt = (m + term) // 12
if year_cnt > 0:
y += year_cnt
m += term - year_cnt * 12
else:
m += term
3. 결국 블로그를 찾아보고 알았다. m+term을 12개월로 나누고 몫은 y에 나머지는 m에 더해주면, 나누어 떨어졌을 때 m이 0이 된다.
왜 이 생각을 못 했을까....
dy, dm = divmod(m + term, 12)
if dm == 0:
dy -= 1
m = 12
else:
m += term
y += dy
오늘과 날짜 비교
그냥 대충 앞에서 걸러지겠거니 생각했던 것.
음.. 처음부터 똑바로 풀자. 처음에 그지같이 풀면 그 안에서 헤어나오지 못하게 되는 것 같다. 하
if y < year:
return True
if m < month:
return True
if d < day:
return True
return False
수정한 코드
if y < year:
return True
if y == year and dm < month:
return True
if y == year and dm == month and d <= day:
return True
return False
참고한 블로그에서는 그냥 문자열 형태로 대소비교를 했더라.
그렇게 하는게 더 코드가 깔끔할듯
최종 코드
def solution(today, terms, privacies):
def cal_date(y, m, d, term):
nonlocal year
nonlocal month
nonlocal day
dy, dm = divmod(m + term, 12)
if dm == 0:
dy -= 1
dm = 12
y += dy
if y < year:
return True
if y==year and dm < month:
return True
if y==year and dm==month and d <= day:
return True
return False
answer = []
year, month, day = map(int, today.split("."))
# 약관 종류 딕셔너리에 저장
terms_d = {}
for term in terms:
t, m = map(str, term.split(" "))
terms_d[t] = int(m)
for i in range(len(privacies)):
date, typ = map(str, privacies[i].split(" "))
y, m, d = map(int, date.split("."))
if cal_date(y, m, d, terms_d[typ]):
answer.append(i + 1)
return answer
블로그 참고한 코드
def solution(today, terms, privacies):
answer = []
year, month, day = map(str, today.split("."))
terms_d = {}
for term in terms:
term_type, term_month = term.split()
terms_d[term_type] = int(term_month)
for i in range(len(privacies)):
date, typ = privacies[i].split()
y, m, d = date.split(".")
dy, dm = divmod(int(m) + terms_d[typ], 12)
if dm == 0:
dy -= 1
dm = 12
y = int(y) + dy
if dm < 10:
dm = "0" + str(dm)
expire_date = str(y) + str(dm) + str(d)
today_date = year + month + day
if expire_date <= today_date:
answer.append(i + 1)
return answer
회고
이렇게까지 삽질했던 문제가 있었던가..
처음 풀 때 집중 안하고 너무 대충 풀어서 너무 고생했다. 앞으론 꼭 처음부터 제대로 풀 것
프로그래머스에 다른 풀이를 보니 년도랑 월수를 다 일자로 변환해서 푸는 풀이도 있더라.
참고
'코테 준비' 카테고리의 다른 글
[프로그래머스] 숫자 변환하기 (python) (2) | 2024.03.16 |
---|---|
[프로그래머스] 미로 탈출 명령어 (python) (2) | 2024.03.15 |
[프로그래머스] 거리두기 확인하기 (Python) (2) | 2024.03.14 |
[프로그래머스] 광물 캐기 (Python) (0) | 2024.03.13 |
[프로그래머스] k진수에서 소수 개수 구하기 (python) (1) | 2024.03.08 |