반응형
🔍 문제 요약
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보다 직접 계산이 더 나을 수 있다는 점을 유의하자
반응형
'Coding Test > Programmers' 카테고리의 다른 글
[Lv.1] 문자열 내 마음대로 정렬하기 [프로그래머스_코딩테스트] [문자열] [25분] (1) | 2025.06.13 |
---|---|
[Lv.1] 이상한 문자 만들기 [프로그래머스_코딩테스트] [문자열] [20분] (0) | 2025.06.12 |
[Lv.1] 서울에서 김서방 찾기 [프로그래머스_코딩테스트] [문자열, 구현] [10분] (0) | 2025.06.11 |
[Lv.2] 가장 큰 수 [프로그래머스_코딩테스트] [정렬, 문자열] [35분] (0) | 2025.06.11 |
[Lv.1] 문자열 내림차순으로 배치하기 [프로그래머스_코딩테스트] [문자열, 정렬] [20분] (1) | 2025.06.10 |