본문 바로가기
코테 준비

[프로그래머스] 개인정보 수집 유효기간 (Python)

by 박수련 2024. 3. 14.

문제 요약

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

 

 

회고

이렇게까지 삽질했던 문제가 있었던가..

처음 풀 때 집중 안하고 너무 대충 풀어서 너무 고생했다. 앞으론 꼭 처음부터 제대로 풀 것 

프로그래머스에 다른 풀이를 보니 년도랑 월수를 다 일자로 변환해서 푸는 풀이도 있더라. 

 

참고

https://velog.io/@nembizzang/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV1.%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4-%EC%88%98%EC%A7%91-%EC%9C%A0%ED%9A%A8%EA%B8%B0%EA%B0%84#:~:text=%EC%98%88%EB%A5%BC%20%EB%93%A4%EC%96%B4%2C%20A%EB%9D%BC%EB%8A%94,%ED%95%B4%EC%95%BC%20%ED%95%A0%20%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4%EC%9E%85%EB%8B%88%EB%8B%A4.