Coding Test/Programmers

[Lv.1] 개인정보 수집 유효기간 [프로그래머스_코딩테스트] [문자열, 날짜 처리] [2023 KAKAO BLIND RECRUITMENT][30분]

whawoo 2025. 6. 12. 23:27
반응형

🔍 문제 요약

https://school.programmers.co.kr/learn/courses/30/lessons/150370

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

약관 종류에 따른 유효기간 (달)로 주어졌을 때 개인 정보 수집 일자와 약관 종류 배열 privacies을 주고 오늘 날짜 today를 주었을 때 유효기간이 지난 약관의 번호를 가져오는 문제

🧠 나의 접근 방식과 시행착오

한 달이 28일이라는 제한 조건이 걸리면서 생각외로 시간을 잡아먹었다.. 게임 개발을 하면서 자주 썼던 DateTime을 쓰긴 했는데 년도 차이, 월 차이, 날짜 차이를 하면서 -1씩 해주는 거를 하고 합산을 하면서 실수를 했었던 부분.. 한 40분 정도 소요된 듯 하다. 예상외로 오래 걸렸던 문제. 난이도 자체는 어렵지 않은 문제긴 하다

using System;
using System.Collections.Generic;

public class Solution
{
    /// <summary>
    /// 개인정보 수집 유효기간
    /// https://school.programmers.co.kr/learn/courses/30/lessons/150370
    /// </summary>
    public int[] solution(string today, string[] terms, string[] privacies)
    {
        // 오늘 날짜를 비교하기 쉽게 DateTime으로 Parse
        DateTime todayDate = DateTime.Parse(today);
        
        // terms Dict로 바꾸기
        Dictionary<char, int> termDict = new Dictionary<char, int>();
        
        foreach (var str in terms)
        {
            var strArr = str.Split(' ');

            char term = char.Parse(strArr[0]);
            int month = int.Parse(strArr[1]);
            
            termDict.Add(term, month);
        }
        
        List<(DateTime, char)> privaciList = new List<(DateTime, char)>();

        foreach (var str in privacies)
        {
            var strArr = str.Split(' ');
            var date = DateTime.Parse(strArr[0]);
            var term = char.Parse(strArr[1]);
            
            privaciList.Add((date, term));
        }
        
        List<int> resList = new List<int>();

        for (int i = 0; i < privaciList.Count; i++)
        {
            if (termDict.TryGetValue(privaciList[i].Item2, out var month))
            {
                var date = privaciList[i].Item1;
                var yearDiff = todayDate.Year - date.Year;
                var monthDiff = 0;
                int dayDiff = 0;

                if (yearDiff > 0)
                {
                    monthDiff = 12 - date.Month + todayDate.Month;
                    yearDiff -= 1;
                }
                else
                {
                    monthDiff = todayDate.Month - date.Month;
                }

                if (monthDiff > 0)
                {
                    dayDiff = 28 - date.Day + todayDate.Day;
                    monthDiff -= 1;
                }
                else
                {
                    dayDiff = todayDate.Day - date.Day;
                }
                
                // 한달 28일로 가정
                if (yearDiff * (28 * 12) + monthDiff * 28 + dayDiff >= month * 28)
                {
                    resList.Add(i + 1);
                }
            }
        }
        
        return resList.ToArray();
    }
}

/// <summary>
/// C# 7.3
/// </summary>
internal class Program
{
    public static void Main(string[] args)
    {
        var sl = new Solution();
        var today = "2020.01.01";
        var terms = new[] { "Z 3", "D 5" };
        var privacies = new [] {"2019.01.01 D", "2019.11.15 Z", "2019.08.02 D", "2019.07.01 D", "2018.12.28 Z"};
        var res = sl.solution(today, terms, privacies);

        for (int i = 0; i < res.Length; i++)
        {
            Console.Write(res[i] + ", ");
        }
    }
}

✅ 풀이 코드

오히려 dateTime을 써서 코드가 복잡해졌다는 것을 피드백을 주었다. 이건 확실히 맞는 말.. 그냥 스트링 parse시켜서 아래처럼 ConvertToDay로 날짜로 변환을 시키고 해당 날짜 끼리로 비교를 하면 되긴 하다

int ConvertToDays(string date)
{
    var parts = date.Split('.');
    int y = int.Parse(parts[0]);
    int m = int.Parse(parts[1]);
    int d = int.Parse(parts[2]);

    return (y * 12 * 28) + (m * 28) + d;
}

public int[] solution(string today, string[] terms, string[] privacies)
{
    int todayDays = ConvertToDays(today);
    Dictionary<string, int> termDict = new Dictionary<string, int>();
    foreach (var term in terms)
    {
        var split = term.Split();
        termDict[split[0]] = int.Parse(split[1]);
    }

    List<int> result = new List<int>();
    for (int i = 0; i < privacies.Length; i++)
    {
        var split = privacies[i].Split();
        int baseDays = ConvertToDays(split[0]);
        int validDays = termDict[split[1]] * 28;

        if (baseDays + validDays <= todayDays)
            result.Add(i + 1);
    }

    return result.ToArray();
}

🔄 정리

실제 날짜 계산을 하는 거에서는 DateTime을 가지고 쓰는게 유용하지만 한달이 n일이다 같은 식으로 규칙이 정해지게 된다면 DateTime보다 직접 계산이 더 나을 수 있다는 점을 유의하자

반응형