본문 바로가기
프로그래머스 코딩테스트 문제/Level 1

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

by jyppro 2023. 9. 22.

개인정보 수집 유효기간

오늘은 2023 KAKAO BLIND RECRUITMENT 출제문제인 "개인정보 수집 유효기간" 문제를 풀어보도록 하겠습니다. 이 문제의 정답률은 41%입니다. 바로 문제 살펴보겠습니다.

 

문제 설명

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

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

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

다음은 오늘 날짜가 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]입니다.

오늘 날짜를 의미하는 문자열 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에 나타난 약관 종류만 주어집니다.
  • today와 privacies에 등장하는 날짜의 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]

 

입출력 예 설명

입출력 예 #1
문제 예시와 같습니다.


입출력 예 #2

약관 종류 유효기간
Z 3 달
D 5 달
번호 개인정보 수집 일자 약관 종류
1 2019.01.01 D
2 2019.11.15 Z
3 2019.08.02 D
4 2019.07.01 D
5 2018.12.28 Z

오늘 날짜는 2020년 1월 1일입니다.

  • 첫 번째 개인정보는 D약관에 의해 2019년 5월 28일까지 보관 가능하며, 유효기간이 지났으므로 파기해야 할 개인정보입니다.
  • 두 번째 개인정보는 Z약관에 의해 2020년 2월 14일까지 보관 가능하며, 유효기간이 지나지 않았으므로 아직 보관 가능합니다.
  • 세 번째 개인정보는 D약관에 의해 2020년 1월 1일까지 보관 가능하며, 유효기간이 지나지 않았으므로 아직 보관 가능합니다.
  • 네 번째 개인정보는 D약관에 의해 2019년 11월 28일까지 보관 가능하며, 유효기간이 지났으므로 파기해야 할 개인정보입니다.
  • 다섯 번째 개인정보는 Z약관에 의해 2019년 3월 27일까지 보관 가능하며, 유효기간이 지났으므로 파기해야 할 개인정보입니다.

시작 코드

using System;

public class Solution {
    public int[] solution(string today, string[] terms, string[] privacies) {
        int[] answer = new int[] {};
        return answer;
    }
}

 

나의 풀이

/* 개인정보 n개(1부터 번호로 분류), 약관마다 유효기간
 오늘날짜로 파기해야할 개인정보 번호 구하기
 모든 달은 28일까지
 오늘날짜 : today, 유효기간 문자열 배열 : terms, 개인정보의 정보 문자열 배열 : privacies
 파기해야할 정보 번호를 오름차순으로 1차원 정수 배열에 담아 리턴 */

using System;
using System.Collections.Generic;
public class Solution
{
    public int[] solution(string today, string[] terms, string[] privacies)
    {
        List<int> answer = new List<int>(); // 리스트 생성
        DateTime todayDate = DateTime.Parse(today); // today를 날짜타입으로 변환

        Dictionary<string, string> termsDic = new Dictionary<string, string>(); //딕셔너리 생성

        for (int i = 0; i < terms.Length; i++)
        {
            string[] st = terms[i].Split(" "); // 공백문자를 기준으로 배열 자르기
            termsDic.Add(st[0], st[1]); // 딕셔너리에 요소 인덱스 순서대로 추가
        }

        for (int i = 0; i < privacies.Length; i++)
        {
            string[] sp = privacies[i].Split(" ");

            // 딕셔너리에서 sp[1]과 같은 키값을 가지는 요소가 있다면
            if (termsDic.TryGetValue(sp[1], out string value))
            {
                // 찾은 요소의 밸류값을 int형으로 파싱 후, 날짜타입으로 파싱된 sp[0]에 AddMonths를 통해 월단위 증가
                DateTime privacie = DateTime.Parse(sp[0]).AddMonths(int.Parse(value));

                // 오늘날짜와 계산된 만료일자와 비교했을 때, 오늘날짜가 만료일자보다 작지 않으면
                if (todayDate.CompareTo(privacie) != -1)
                {
                    answer.Add(i + 1); // 정답에 (인덱스 번호 + 1) 추가
                }
            }
        }
        answer.Sort(); // 정답 오름차순 정렬
        return answer.ToArray(); // 배열형태로 리턴
    }
}

 

코드 분석

string타입의 문자열 today와 배열 terms, privacies가 주어지며 코드가 시작됩니다. int형 배열로 존재하던 answer를 리스트로 바꿔주고 today를 DateTime 타입으로 바꿔 todayDate라고 선언해줍니다. 그리고 string이 두개 들어갈 수 있 딕셔너리를 termsDic라는 이름으로 선언해줍니다.

 

for문으로 i = 0부터 terms의 길이만큼 돌리고 그 안에 string타입 배열 st를 선언해 terms[i]를 .Split(" ")을 이용해 공백을 기준으로 잘라 넣어줍니다. 그리고 termsDic에 st[0]과 st[1]을 넣어줍니다.

 

다음에는 큰 for문 하나에 중첩 if문이 들어있습니다. for문은 i = 0부터 privacies의 길이까지 돌며 string타입 배열 sp에 privacies[i]를 공백으로 나눠 넣어줍니다. 이후 첫 if문에서 termsDic.TryGetValue(sp[1], out string value)를 충족하면 DateTime타입 privacie를 만들고 value값을 int형으로 변환 후 sp[0]에 DateTime형으로 파싱하여 월단위로 넣어줍니다.

 

다음 if문은 todayDate.CompareTo(privacie)의 값이 -1이 아니면 answer에 i+1을 Add해줍니다. 마지막으로 answer를 Sort로 정렬해주고 배열형태로 바꿔 리턴해주면 코드가 끝이 납니다.

 

풀이 설명

문제의 요구사항은 파기해야 할 개인정보의 번호를 모아 배열로 만드는 것입니다. 계산과정을 쉽게 하기 위해 answer를 리스트로 바꾸고 날짜를 표현하는 형식인 DateTime과 함께 딕셔너리를 선언해줍니다.

 

첫 for문에서는 terms를 쪼개고 딕셔너리에 추가해서 키, 값의 형태로 약관에 따른 개월 수를 나타내도록 만들어주고, 두번째 for문에서는 privaices를 이용해 termsDic에 들어간 약관의 종류를 sp[1]와 비교하여 같은 것이 있다면 해당 키값의 value를 int형으로 변환시킨 뒤 DateTime형으로 파싱된 sp[0]에 AddMonth를 하여 privacie를 만들어줍니다. 이후 마지막 if문은 todayDate와 만들어진 privacie를 비교하여 todayDate가 더 작지 않다면 answer i + 1을 넣어줍니다. 그러면 파기해야 할 날짜에 대한 인덱스 번호가 오름차순으로 정리된 배열의 형태로 만들어집니다.

 

<NEXT>

오늘은 2023 KAKAO BLIND RECRUITMENT 출제문제인 "개인정보 수집 유효기간" 문제를 풀어보았습니다. 앞으로 프로그래머스 레벨 1의 문제는 총 3문제가 남았습니다. 다음에는 "달리기 경주" 문제를 풀어보도록 하겠습니다. 감사합니다.