ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로그래머스 개인정보 수집 유효기간(2023 KAKAO BLIND RECRUITMENT) Python
    코딩 테스트 2023. 2. 7. 15:45

    문제 링크

     

    today가 정해진 약관 내에 있지 않으면 배열로 리턴하는 문제이다.

     

    최초 통과 코드

    #약관 딕셔너리로 표현
    def make_rules(terms):
        rules={}
        for r in terms:
            a,b=r.split()
            rules[a] = int(b)
        return rules
    
    # '.'을 구분자로 해 배열로 반환
    def split_date(today):
        today_list=list(map(int,today.split('.')))
        return today_list
    
    #약관만큼의 개월수를 더하기
    def policy_apply(dates_data, n, i):
        dates_data[i][1] += n
        while dates_data[i][1] > 12:
            dates_data[i][1] -= 12
            dates_data[i][0] += 1
        return dates_data[i]
    
    #약관만큼 더한 값과 오늘의 날짜를 비교해 boolean 반환
    def compare(today_list, dates_data, i):
        if today_list[0] < dates_data[i][0]:    
            return False;
        elif today_list[0] > dates_data[i][0]:
            return True;
        elif today_list[1] < dates_data[i][1]: 
            return False;
        elif today_list[1] > dates_data[i][1]:
            return True;
        elif today_list[2] < dates_data[i][2]:
            return False;
        else:
            return True;
            
    def solution(today, terms, privacies):
        answer = []
        dates_data=[]
        rules_data=[]
        rules=make_rules(terms)
        today_list=split_date(today)
        for i in range(len(privacies)):
            str_data, rule_data=privacies[i].split()
            rules_data.append(rule_data)
            dates_data.append(split_date(str_data))
        for i in range(len(privacies)):
            n = rules[rules_data[i]]
            dates_data[i]=policy_apply(dates_data, n, i)
            if compare(today_list, dates_data, i):
                answer.append(i+1)
        return answer

    약관을 딕셔너리로 표현했고, 연도,월,일을 배열의 0,1,2번째 원소로 지정해 2차원 배열을 사용했다.

    최초에 코드를 다 짜고 나서 정확도가 40%로 테스트케이스를 전부 만족시키지 못해서 어디가 문제인지 찾다가... 조건에 terms의 최대가 20인걸 보고 아차 싶었다. 너무 당연하게 최대를 12로 생각하고 policy_apply함수에서 while문이 아닌 if문으로 짰었던 것이다.. 

     

    다른 풀이

    def solution(today, terms, privacies):
        answer = []
        # 년,월,일을 분해해서 일 단위로 통일
        y,m,d = today.split('.')
        today = int(y)*12*28 + int(m)*28 + int(d)
    
        # 약관 종류를 딕셔너리 형태로 바꿔줌 (약관 종류:유효기간(일 단위))
        terms = {i[:1]:int(i[1:])*28 for i in terms}
    
        # p : privacies 원소(수집일자)를 '일'단위로 치환
        # c : 약관종류
        for i,p in enumerate(privacies):
            y,m,d = p.split('.')
            d,c = d.split()
            p = int(y)*12*28 + int(m)*28 + int(d)
            # (수집일자 + 약관종류에 따른 일자)가 오늘을 넘지 않으면 정답(인덱스+1)에 추가
            if p+terms[c] <= today:
                answer.append(i+1)
    
        return answer

    다른 풀이로는 조건을 더 활용해(모든 월의 일이 최대28) 연도와 월을 전부 일로 변환해서 일로만 비교하며, slicing을 써서(i[:1]같이) 코드를 간단하게 표현할 수 있다.

     

    역시 조건은 힌트와 함정이 공존한다는 것을 깨달으며 앞으로 조건을 꼼꼼히 보겠다고 다짐한다.

    댓글

Designed by Tistory.