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

Taemin Jang·2023년 1월 11일
0

코딩테스트

목록 보기
1/9
post-thumbnail

문제 출처

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

문제 설명

고객의 약관 동의를 얻어서 수집된 1~n번으로 분류되는 개인정보 n개가 있습니다. 약관 종류는 여러 가지 있으며 각 약관마다 개인정보 보관 유효기간이 정해져 있습니다. 당신은 각 개인정보가 어떤 약관으로 수집됐는지 알고 있습니다. 수집된 개인정보는 유효기간 전까지만 보관 가능하며, 유효기간이 지났다면 반드시 파기해야 합니다.

예를 들어, A라는 약관의 유효기간이 12 달이고, 2021년 1월 5일에 수집된 개인정보가 A약관으로 수집되었다면 해당 개인정보는 2022년 1월 4일까지 보관 가능하며 2022년 1월 5일부터 파기해야 할 개인정보입니다.
당신은 오늘 날짜로 파기해야 할 개인정보 번호들을 구하려 합니다.

모든 달은 28일까지 있다고 가정합니다.

오늘 날짜를 의미하는 문자열 today, 약관의 유효기간을 담은 1차원 문자열 배열 terms와 수집된 개인정보의 정보를 담은 1차원 문자열 배열 privacies가 매개변수로 주어집니다. 이때 파기해야 할 개인정보의 번호를 오름차순으로 1차원 정수 배열에 담아 return 하도록 solution 함수를 완성해 주세요.


제한사항
  • 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에 나타난 약관 종류만 주어집니다.
  • todayprivacies에 등장하는 날짜YYYY는 연도, MM은 월, DD는 일을 나타내며 점(.) 하나로 구분되어 있습니다.
    • 2000 ≤ YYYY ≤ 2022
    • 1 ≤ MM ≤ 12
    • MM이 한 자릿수인 경우 앞에 0이 붙습니다.
    • 1 ≤ DD ≤ 28
    • DD가 한 자릿수인 경우 앞에 0이 붙습니다.
  • 파기해야 할 개인정보가 하나 이상 존재하는 입력만 주어집니다.

입출력 예
today terms privacies result
"2022.05.19" ["A 6", "B 12", "C 3"] ["2021.05.02 A", "2021.07.01 B", "2022.02.19 C", "2022.02.20 C"] [1, 3]
"2020.01.01" ["Z 3", "D 5"] ["2019.01.01 D", "2019.11.15 Z", "2019.08.02 D", "2019.07.01 D", "2018.12.28 Z"] [1, 4, 5]

나의 풀이

function solution(today, terms, privacies) {
    // 현재 날짜 [연, 월, 일]로 저장
    let current = today.split(".").map(v => +v);
    
    // 약관 종류가 {A: '6', B: '12'} 이런식으로 저장됨
    let termsKind = {};
    
    // 배열로 저장되어 있는 약관 정보를 알아보기 쉽게 하기 위해 termsKind라는 객체에 저장
    terms.forEach(v => {
        let [kind, period] = v.split(" ");
        termsKind[kind] = period; 
    })
    
    // 파기해야하는 개인정보 인덱스를 저장 
    let result = [];
    
    // 개인정보들을 for문 돌리면서 현재 날짜를 비교해 파기해야할 정보를 result에 넣어준다
    privacies.forEach((v,i) => {
        // 구조식 분해로 past에는 개인정보 수집 일자, kind에는 약관 종류가 저장
        let [past, kind] = v.split(" ");
        // 마찬가지로 개인정보 수집 일자를 년, 월, 일로 숫자 변환 후 저장
        let [y,m,d] = past.split(".").map(v => +v);
        // 개인정보 수집 일자 달에 약관 종류에 맞는 유효 기간을 더함 
        m+=+termsKind[kind];
        // 보관 가능 날짜는 유효기간 하루 전날까지라서 하루를 빼줌
        d--;
        
        // 만약 달이 12보다 클 경우
        if(m>12){
            // 달을 12으로 나눴을 때
            if(m % 12 === 0){
                // 12의 배수이면 년도는 바뀌지 않음
                y += parseInt(m/12) - 1;
                // 0이면 12월 
                m = 12;
            }else{
                // 12의 배수가 아닌 경우는 년도가 바뀜
                y += parseInt(m/12);
                // 아닐경우 12로 나눈 나머지
                m = m % 12;
            }
        }
        // d-- 해서 일자가 0이 된 경우
        if(d === 0){
            // 0일인 경우는 없으므로 전달로 넘어가기 위해
            m--;
            // 전달로 넘어가면 그 달의 마지막 일인 28로 저장
            d=28;
             // m-- 해서 달이 0이 된 경우
            if(m === 0){
                // 0달인 경우는 없으므로 전년도로 넘어가기 위해
                y--;
                // 전년도로 넘어가면 그 해의 마지막 달인 경우 12로 저장
                m=12;
            }
        }
        // 만약 유효기간의 년도보다 현재 년도가 클 경우
        if(y < current[0]){
            // 해당 개인정보 인덱스 값을 +1한 후 result에 저장
            result.push(i+1);
            return;
        // 만약 년도가 같을 경우
        }else if(y === current[0]){
            // 유효기간의 달보다 현재의 달이 클 경우
            if(m < current[1]){
                result.push(i+1);
                return;
            // 먄약 달이 같을 경우
            }else if(m === current[1]){
                // 유효기간의 일수보다 현재의 일수가 더 클경우
                if(d < current[2]){
                    result.push(i+1);
                    return;
                }
            }
        }
    })
    return result;
}

풀이는 생각보다 어렵지 않았지만, 날짜 계산이라 생각지 못한 경우의 수들이 좀 어려웠다.

특히 년도를 12로 나눈 몫을 더해줬는데, 12의 배수 즉 월이 12, 24, 36이렇게 되면 12개월, 1년 12개월, 2년 12개월이 되어야한다.

맨 처음에는 y += parseInt(m/12); 이렇게 그냥 12로 나눠서 더해줘가지고 12월인데 1년을 더해주게 되는 문제가 있었다. 만약 12의 배수면 y += parseInt(m/12) - 1;을 해서 구분해주면 된다.

다른 풀이로는 new Date()를 써서 푸신 분들도 있고, 아니면 년, 월, 일을 다 일로 바꿔서 비교하신 분들도 있다.

어느 풀이가 맞다고 할 수는 없지만, 다양한 풀이를 보면서 문제 풀이 관점을 넓히면 좋을 것 같다.

profile
하루하루 공부한 내용 기록하기

0개의 댓글