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

gcoco·2023년 5월 11일
0

안녕하세요! 조금은 성장한듯한 GCOCO입니다!


잡설 한 COOKIE🍪

여러분은... 패배의 경험이 있으십니까?
당연히 있을것입니다! 최소 1~5살 사이엔 반드시 한 번 쯤은 패배했을것이라고 생각합니다!
물론 그걸 묻자는게 아니구요. 성장하는 과정에서의 패배입니다.
저는 패배한적이 꽤나 많습니다. 어린 초,중학생때는 '나..꽤나 특출날지도?!' 하고 착각했던때도 있었지만
나이를 먹고 정말로 훌륭하신 '진짜'들을 보면서 수없이 패배하고 또한 스스로의 성장을 위해 학습을 하는 과정에서도 굉장히 많은 패배를 하였습니다.

오늘 소개해드릴 문제는 프로그래머스 LV1에서 세번째로 정답률이 낮은 문제로 저도 이 문제를 예전에 풀면서 굉장히 괴로워했던 기억이 새록새록 납니다. 그 당시 푸는데 2일이 걸렸던 것 같습니다.

이번에 새롭게 풀면서는 한 25분정도 걸린거 같습니다만, 여전히 푸는 속도가 느렸음을 느꼈습니다.

그럼에도 불구하고 과거에 비해 성장했다는 것에 만족합니다!

앞으로도 전 끊임없이 도전하고 패배하고 쓴 맛을 볼 테지요. 그러나 가장 중요한 것은?

"개쩌는 코딩 실력"

이 아니라.... "꺾이지 않는 마음"이지 않겠습니까!

좋습니다. 저와 함께 가 보시죠!


문제링크:

옛풀이


#include <string>
#include <vector>
#include <sstream>
#include <iostream>

using namespace std;

vector<int> solution(string today, vector<string> terms, vector<string> privacies) {
    vector<int> answer;
    int t_year, t_month, t_day;
    t_year = stoi(today.substr(0, 4));
    t_month = stoi(today.substr(5, 2));
    t_day = stoi(today.substr(8, 2));
    cout << "today: " << t_year << t_month << t_day << endl;

    int k = 1;//파기 대상 privacies를 담기 위한 index
    for (auto i : privacies) {
        for (auto j : terms) {
            if (j.front() == i.back()) {
                int year, month, day, tmp;
                char c;
                year = stoi(i.substr(0, 4));
                month = stoi(i.substr(5, 2));
                day = stoi(i.substr(8, 2));
                stringstream s;
                s.str(j);
                s >> c >> tmp;
                month += tmp;
                day--;
                if (day == 0) {
                    day = 28;
                    month--;
                }
                if (month == 0) {
                    month = 12;
                    year--;
                }
                else if (month > 12) {
                    while (month > 12) {
                        year++;
                        month -= 12;
                    }
                }
                cout << "유효기간 :" << year << " " << month << " " << day << endl;
				//파기 해당 여부 if문
                if (year > t_year) {
                    k++;
                    break;
                }
                else if (year < t_year) {
                    answer.emplace_back(k++);
                    break;
                }
                else {
                    if (month > t_month) {
                        k++;
                        break;
                    }
                    else if (month < t_month) {
                        answer.emplace_back(k++);
                        break;
                    }
                    else {
                        if (day >= t_day) {
                            k++;
                            break;
                        }
                        else {
                            answer.emplace_back(k++);
                            break;
                        }
                    }
                }
            }
        }
    }

    return answer;
}

캬........무수한 if와 else의 요청이!!! 저의 고민의 흔적이 느껴지실까요?
코드는 길지만 결국 하고싶은것은 c와 tmp에 종류와 보관기한을 받아
약관일로부터 보관기한만큼 만료일을 계산하여 오늘과 비교한다는 내용의 코드입니다.

하지만 한눈에 알아보는것이 정말 어렵습니다.
특히나 if문의 조건이 난잡하여 더 어렵게 하는것 같습니다.
그 당시의 if문을 짜던 저의 고통이 스물스물 느껴지는군요.....

새로운 풀이를 보며 스텝을 밟아봅시다.


새풀이

#include <string>
#include <vector>
#include <sstream>

using namespace std;

vector<int> solution(string today, vector<string> terms, vector<string> privacies) {
    vector<int> answer;
    int size = privacies.size();
    for(int i=0;i<size;i++){
        int stand = stoi(today.substr(0,4))*12*28+(stoi(today.substr(5,2))-1)*28+stoi(today.substr(8,2));
        char term = privacies[i].back();
        char alpha;
        int duration;
        for(auto i:terms){
            stringstream ss;
            ss.str(i);
            ss>>alpha>>duration;
            if(alpha==term){
                break;
            }
        }

        int trans =stoi(privacies[i].substr(0,4))*12*28+(stoi(privacies[i].substr(5,7))-1)*28
            +stoi(privacies[i].substr(8,10))+duration*28;
     
        if(trans>stand)
            continue;
        else
            answer.emplace_back(i+1);
    }
    return answer;
}

위에서부터 아래까지의 길이로만 따지면 절반은 줄은것 같습니다!

코드의 스텝은 다음과 같습니다.

  1. privacies를 순회할 것.
  2. stand 변수를 통해 기준일을 숫자로 표기
  3. term으로 privacies[i]의 type을 확인
  4. terms를 순회하며 약관type과 보관기일을 alpha와 duration에 받아 term과 일치하는지 확인
  5. trans 변수에 기준일+보관기일 하여 숫자로 표기
  6. trans>stand 즉 보관만료일이 오늘보다 멀다면, pass.
  7. 보관기간 만료라면 answer에 담기

확실히 코드는 생각의 흐름처럼 자연스레 나타날 때 가장 읽기도, 쓰기도 쉬운것 같습니다!

눈 여겨볼 점은 substr함수가 아주 유용하게 사용되었다는 것입니다.
또한 stringstream을 이용하여 terms의 약관type과 보관기일을 손쉽게 추출했다는 점입니다.


도움이 되셨다면, 다행입니다! 이상 포스팅 마치겠습니다.

profile
그코코 입니다.

0개의 댓글