https://school.programmers.co.kr/learn/courses/30/lessons/150370
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
- 1~n번으로 분류되는 개인정보 n개
- 약관 종류는 여러 가지 있으며 각 약관마다 개인정보 보관 유효기간이 정해져 있음
- 각 개인정보가 어떤 약관으로 수집됐는지 알고 있음
- 수집된 개인정보는 유효기간 전까지만 보관 가능하며, 유효기간이 지났다면 반드시 파기해야 함
- ex) A라는 약관의 유효기간이 12 달이고, 2021년 1월 5일에 수집된 개인정보가 A약관으로 수집되었다면
- 해당 개인정보는 2022년 1월 4일까지 보관 가능
- 2022년 1월 5일부터 파기해야 할 개인정보
- 오늘 날짜로 파기해야 할 개인정보 번호들을 구하려 함
- 모든 달은 28일까지 있다고 가정
- today: 오늘 날짜를 의미하는 문자열
- terms: 약관의 유효기간을 담은 1차원 문자열 배열
- privacies: 수집된 개인정보의 정보를 담은 1차원 문자열 배열
- 파기해야 할 개인정보의 번호를 오름차순으로 1차원 정수 배열에 담아 return
제한사항
- today는 "YYYY.MM.DD" 형태로 오늘 날짜를 나타냄
- 1 ≤ terms의 길이 ≤ 20
- terms의 원소는 "약관 종류 유효기간" 형태의 약관 종류와 유효기간을 공백 하나로 구분한 문자열
- 약관 종류는 A~Z중 알파벳 대문자 하나이며, terms 배열에서 약관 종류는 중복되지 않음
- 유효기간은 개인정보를 보관할 수 있는 달 수를 나타내는 정수이며, 1 이상 100 이하
- 1 ≤ privacies의 길이 ≤ 100
- privacies[i]는 i+1번 개인정보의 수집 일자와 약관 종류
- privacies의 원소는 "날짜 약관 종류" 형태의 날짜와 약관 종류를 공백 하나로 구분한 문자열
- 날짜는 "YYYY.MM.DD" 형태의 개인정보가 수집된 날짜를 나타내며, today 이전의 날짜만 주어짐
- privacies의 약관 종류는 항상 terms에 나타난 약관 종류만 주어짐
- today와 privacies에 등장하는 날짜의 YYYY는 연도, MM은 월, DD는 일을 나타내며 점(.) 하나로 구분
- 2000 ≤ YYYY ≤ 2022
- 1 ≤ MM ≤ 12
- MM이 한 자릿수인 경우 앞에 0이 붙음
- 1 ≤ DD ≤ 28
- DD가 한 자릿수인 경우 앞에 0이 붙음
- 파기해야 할 개인정보가 하나 이상 존재하는 입력만 주어짐
"""
입출력 예시)
today = "2022.05.19", terms = ["A 6", "B 12", "C 3"], privacies = ["2021.05.02 A", "2021.07.01 B", "2022.02.19 C", "2022.02.20 C"] -> [1, 3]
today = "2020.01.01", terms = ["Z 3", "D 5"], privacies = ["2019.01.01 D", "2019.11.15 Z", "2019.08.02 D", "2019.07.01 D", "2018.12.28 Z"] -> [1, 4, 5]
"""
# today = "2022.05.19", terms = ["A 6", "B 12", "C 3"], privacies = ["2021.05.02 A", "2021.07.01 B", "2022.02.19 C", "2022.02.20 C"] -> [1, 3]
# 오늘 날짜 -> 2022.05.19
# 약관 종류: A, 유효기간: 6달
# 약관 종류: B, 유효기간: 12달
# 약관 종류: C, 유효기간: 3달
# 번호: 1, 개인정보 수집 일자: 2021.05.02, 약관 종류: A
# 번호: 2, 개인정보 수집 일자: 2021.07.01, 약관 종류: B
# 번호: 3, 개인정보 수집 일자: 2022.02.19, 약관 종류: C
# 번호: 4, 개인정보 수집 일자: 2022.02.20, 약관 종류: C
# -> 첫 번째 개인정보는 A약관에 의해 2021년 11월 1일까지 보관 가능하며, 유효기간이 지났으므로 파기해야 할 개인정보
# -> 두 번째 개인정보는 B약관에 의해 2022년 6월 28일까지 보관 가능하며, 유효기간이 지나지 않았으므로 아직 보관 가능
# -> 세 번째 개인정보는 C약관에 의해 2022년 5월 18일까지 보관 가능하며, 유효기간이 지났으므로 파기해야 할 개인정보
# -> 네 번째 개인정보는 C약관에 의해 2022년 5월 19일까지 보관 가능하며, 유효기간이 지나지 않았으므로 아직 보관 가능
# => 파기해야 할 개인정보 번호는 [1, 3]
## 의사코드 ##
# terms의 약관 종류와 privacies의 약관 종류는 같음
# 모든 달은 28일까지만 있음
# terms를 딕셔너리로 변환 -> {약관 종류: 유효기간}
# 날짜: "YYYY.MM.DD" 형태
# 날짜.split('.') 해서 년도, 월, 일로 나눠서 계산
# for i in range(len(privacies)):
# 각 번호별로 보관 가능한 날짜를 구함
# 보관 가능한 날짜 = 개인정보 수집한 달 + 약관 종류의 유효기간, 일자 -1
# 달 수 > 12 이면 (년도 + 1, 달 - 12)
# 만약 개인정보 수집 일자의 일이 1이면 (달 수 -1) + 일자: 28
# 보관 가능 날짜 < today 이면 파기 o
# (-> 보관 가능 날짜가 today와 같거나 today보다 크면 아직 보관 가능)
# return answer # 오름차순 정렬
첫 번째 시도
def solution(today, terms, privacies):
answer = []
terms_dic = {}
y, m, d = map(int, today.split('.'))
# terms를 딕셔너리로 변환
for t in terms:
t_type, t_month = t.split()
terms_dic[t_type] = int(t_month)
for i in range(len(privacies)):
p_date, p_type = privacies[i].split()
p_y, p_m, p_d = map(int, p_date.split('.'))
# 보관 가능 날짜 계산
p_m += terms_dic[p_type] # 수집한 달 + 유효기간(달)
# 개인정보 수집 일자의 일이 1인 경우
if p_d == 1:
p_m -= 1
p_d == 28
# 개인정보 수집 일자의 일이 1이 아닌 경우
else:
p_d -= 1 # 수집한 일 - 1
# 보관 가능한 달이 12보다 크면
while p_m > 12:
p_y += 1
p_m -= 12
# today와 보관 가능 날짜 비교
if p_y > y: # 보관 가능 년도가 today의 년도보다 큰 경우
continue
elif p_y == y: # 보관 가능 년도가 today의 년도와 같은 경우
if p_m > m: # 보관 가능 달이 today의 달보다 크면
continue
elif p_m == m: # 보관 가능 달이 today의 달과 같으면
if p_d >= d: # 보관 가능 일이 today의 일보다 크거나 같은 경우
continue
# 보관 가능 날짜가 today보다 작은 경우(이미 지난 경우)
answer.append(i+1) # i의 순서대로 삽입되기 때문에 자동으로 오름차순 정렬
return answer
-> 추가 테스트 케이스 2개 실패 (테스트 5, 테스트 13)
두 번째 시도
def solution(today, terms, privacies):
answer = []
terms_dic = {}
y, m, d = map(int, today.split('.'))
# terms를 딕셔너리로 변환
for t in terms:
t_type, t_month = t.split()
terms_dic[t_type] = int(t_month)
for i in range(len(privacies)):
p_date, p_type = privacies[i].split()
p_y, p_m, p_d = map(int, p_date.split('.'))
# 보관 가능 날짜 계산
p_m += terms_dic[p_type] # 수집한 달 + 유효기간(달)
# 보관 가능한 달이 12보다 크면
while p_m > 12:
p_y += 1
p_m -= 12
# 개인정보 수집 일자의 일이 1인 경우
if p_d == 1:
# 보관 가능 날짜가 1월 1일인 경우
if p_m == 1:
p_y -= 1
p_m == 12
p_d == 28
else:
p_m -= 1
p_d == 28
# 개인정보 수집 일자의 일이 1이 아닌 경우
else:
p_d -= 1 # 수집한 일 - 1
# today와 보관 가능 날짜 비교
if p_y > y: # 보관 가능 년도가 today의 년도보다 큰 경우
continue
elif p_y == y: # 보관 가능 년도가 today의 년도와 같은 경우
if p_m > m: # 보관 가능 달이 today의 달보다 크면
continue
elif p_m == m: # 보관 가능 달이 today의 달과 같으면
if p_d >= d: # 보관 가능 일이 today의 일보다 크거나 같은 경우
continue
# 보관 가능 날짜가 today보다 작은 경우(이미 지난 경우)
answer.append(i+1) # i의 순서대로 삽입되기 때문에 자동으로 오름차순 정렬
return answer
-> 보관 가능 날짜가 1월 1일인 경우 추가
-> 추가 테스트 케이스 3개 실패 (테스트 5, 테스트 13, 테스트 15)
- ex) 보관 가능 날짜가 1월 1일인 경우
- 개인정보 수집 일자: 2020.08.01
- 유효기간: 5달
- -> 2021.01.00 (일자 -1 까지 계산하면)
- => 2020.12.28 까지로 바꿔줘야 함
- 과정 확인
"""
today: 2022.05.19
번호: 1
개인정보 수집 일자: 2021.05.02
유효기간: 6
보관 가능 날짜: 2021 11 1
------------------------------------------------------------
번호: 2
개인정보 수집 일자: 2021.07.01
유효기간: 12
보관 가능 날짜: 2022 6 1
------------------------------------------------------------
번호: 3
개인정보 수집 일자: 2022.02.19
유효기간: 3
보관 가능 날짜: 2022 5 18
------------------------------------------------------------
번호: 4
개인정보 수집 일자: 2022.02.20
유효기간: 3
보관 가능 날짜: 2022 5 19
------------------------------------------------------------
[1, 3]
"""
-> 번호 2의 보관 가능 날짜가 틀림
'번호 2의 보관 가능 날짜: 2022 6 28' 로 나왔어야 함
-> 'p_d == 28' 이 부분이 적용되지 않아서 틀림
=> 변수의 값을 바꾸려고 했던 것이기 때문에 'p_d == 28'이 아닌 'p_d = 28'로 작성했어야 함
- 변수에 저장된 값 바꾸기
# '=' 사용
d = 1
if d == 1:
d = 28
d # -> 28
# cf) '==' 사용
d = 1
if d == 1:
d == 28
d # -> 1
# -> 값이 바뀌지 않음
통과한 코드
- 1) 두 번째 시도 코드 수정
def solution(today, terms, privacies):
answer = []
terms_dic = {}
y, m, d = map(int, today.split('.'))
# terms를 딕셔너리로 변환
for t in terms:
t_type, t_month = t.split()
terms_dic[t_type] = int(t_month)
for i in range(len(privacies)):
p_date, p_type = privacies[i].split()
p_y, p_m, p_d = map(int, p_date.split('.'))
# 보관 가능 날짜 계산
p_m += terms_dic[p_type] # 수집한 달 + 유효기간(달)
# 보관 가능한 달이 12보다 크면
while p_m > 12:
p_y += 1
p_m -= 12
# 개인정보 수집 일자의 일이 1인 경우
if p_d == 1:
# 보관 가능 날짜가 1월 1일인 경우
if p_m == 1:
p_y -= 1
p_m += 11 # 달을 12월로 변환
p_d += 27 # 일을 28일로 변환
else:
p_m -= 1
p_d += 27 # 일을 28일로 변환
# 개인정보 수집 일자의 일이 1이 아닌 경우
else:
p_d -= 1 # 수집한 일 - 1
# today와 보관 가능 날짜 비교
if p_y > y: # 보관 가능 년도가 today의 년도보다 큰 경우
continue
elif p_y == y: # 보관 가능 년도가 today의 년도와 같은 경우
if p_m > m: # 보관 가능 달이 today의 달보다 크면
continue
elif p_m == m: # 보관 가능 달이 today의 달과 같으면
if p_d >= d: # 보관 가능 일이 today의 일과 같거나 큰 경우
continue
# 보관 가능 날짜가 today보다 작은 경우(이미 지난 경우)
answer.append(i+1) # i의 순서대로 삽입되기 때문에 자동으로 오름차순 정렬
return answer
-> 보관 가능 날짜가 1월 1일인 경우, 달 + 11, 일 + 27로 변환하고 보관 가능 일이 today의 일과 같거나 큰 경우로 적용
과정 확인
"""
today: 2022.05.19
번호: 1
개인정보 수집 일자: 2021.05.02
유효기간: 6
보관 가능 날짜: 2021 11 1
------------------------------------------------------------
번호: 2
개인정보 수집 일자: 2021.07.01
유효기간: 12
보관 가능 날짜: 2022 6 28
------------------------------------------------------------
번호: 3
개인정보 수집 일자: 2022.02.19
유효기간: 3
보관 가능 날짜: 2022 5 18
------------------------------------------------------------
번호: 4
개인정보 수집 일자: 2022.02.20
유효기간: 3
보관 가능 날짜: 2022 5 19
------------------------------------------------------------
[1, 3]
"""
-> '번호 2의 보관 가능 날짜: 2022 6 28' 로 제대로 적용됨
- 2) 다른 풀이
- -> 보관 가능 날짜를 계산할 때, (일 - 1) 없이 진행
def solution(today, terms, privacies):
answer = []
terms_dic = {}
y, m, d = map(int, today.split('.'))
# terms를 딕셔너리로 변환
for t in terms:
t_type, t_month = t.split()
terms_dic[t_type] = int(t_month)
for i in range(len(privacies)):
p_date, p_type = privacies[i].split()
p_y, p_m, p_d = map(int, p_date.split('.'))
# 보관 가능 날짜 계산
p_m += terms_dic[p_type] # 수집한 달 + 유효기간(달)
# 보관 가능한 달이 12보다 크면
while p_m > 12:
p_y += 1
p_m -= 12
# today와 보관 가능 날짜 비교
if p_y > y: # 보관 가능 년도가 today의 년도보다 큰 경우
continue
elif p_y == y: # 보관 가능 년도가 today의 년도와 같은 경우
if p_m > m: # 보관 가능 달이 today의 달보다 크면
continue
elif p_m == m: # 보관 가능 달이 today의 달과 같으면
if p_d > d: # 보관 가능 일이 today의 일보다 큰 경우
continue
# 보관 가능 날짜가 today보다 작은 경우(이미 지난 경우)
answer.append(i+1) # i의 순서대로 삽입되기 때문에 자동으로 오름차순 정렬
return answer
-> 개인정보 수집 일자의 일이 1인 경우 삭제, 보관 가능 날짜를 계산할 때 (일 - 1) 없이 진행, 보관 가능 일이 today의 일보다 크거나 같은 경우에서 큰 경우만 continue로 변경
과정 확인
today: 2022.05.19
번호: 1
개인정보 수집 일자: 2021.05.02
유효기간: 6
보관 가능 날짜: 2021 11 2
------------------------------------------------------------
번호: 2
개인정보 수집 일자: 2021.07.01
유효기간: 12
보관 가능 날짜: 2022 7 1
------------------------------------------------------------
번호: 3
개인정보 수집 일자: 2022.02.19
유효기간: 3
보관 가능 날짜: 2022 5 19
------------------------------------------------------------
번호: 4
개인정보 수집 일자: 2022.02.20
유효기간: 3
보관 가능 날짜: 2022 5 20
------------------------------------------------------------
[1, 3]
참고)
[프로그래머스] 개인정보 수집 유효기간 (파이썬) - Lv.1
https://school.programmers.co.kr/learn/courses/30/lessons/150370문제의 조건을 꼼꼼하게 확인하여 하나도 빠짐없이 구현하는게 포인트약관의 종류를 딕셔너리 타입으로 저장각 privacies마다 날짜와 연도를 구하
velog.io
[python] 프로그래머스 코테 - level1. 개인정보 수집 유효기간
문제 > 고객의 약관 동의를 얻어서 수집된 1~n번으로 분류되는 개인정보 n개가 있습니다. 약관 종류는 여러 가지 있으며 각 약관마다 개인정보 보관 유효기간이 정해져 있습니다. 당신은 각 개인
velog.io
'⌨️ Algorithms > 프로그래머스' 카테고리의 다른 글
[Python] 프로그래머스 Lv2_게임 맵 최단거리 (0) | 2023.01.22 |
---|---|
[Python] 프로그래머스 Lv2_타겟 넘버 (0) | 2023.01.21 |
[Python] 프로그래머스 Lv1_삼총사 (0) | 2023.01.13 |
[Python] 프로그래머스 Lv2_카펫 (0) | 2023.01.12 |
[Python] 프로그래머스 Lv2_전력망을 둘로 나누기 (2) | 2023.01.11 |
소중한 공감 감사합니다 :)