Programmersに公開された2023 KAKAO BLIND RECRUITMENT(2023年新入債務第一次オンラインコーディングテスト)の中でLv.1に設定されている個人情報収集有効期間問題です。
1. 問題と条件
問題
お客様の規約の同意を得て収集された1〜n番に分類される個人情報がn個があります。規約種類は色々ありまして、各規約には個人情報保管有効期間が決められています。貴方は各個人情報がどういう規約で収集されたのか知っています。収集された個人情報は有効期間前まで保管可能で、有効期間が過ぎたら必ず破棄しなきゃいけないです。
例えば、Aの規約の有効期間が12ヶ月で、2021年1月5日に収集された個人情報がA規約で収集されていたら、この個人情報は2022年1月4日まで保管可能で2022年1月5日から破棄しないといけない個人情報です。貴方は今日の日付で破棄するべきの個人情報の番号たちを出そうとします。
全ての月は28日まであると仮定します。
入力
今日の日付を意味する文字列today、規約の有効期間が入っている1次元文字列配列termsと収集されている個人情報の情報が入っている1次元文字列配列privaciesがパラメータとして与えられます。
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が1桁の数の場合前に0がつきます。
1 ≤ DD ≤ 28
DDが1桁の数の場合前に0がつきます。
破棄するべきの個人情報が一つ以上存在する入力だけ与えられます。
出力
破棄するべきの個人情報の番号を昇順の1次元整数配列でreturnする。
入出力の例
today | terms | privacies | result |
"2022.05.19" | ["A 6", "B 12", "C 3"] | ["2022.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] |
2. 説明
文字列処理に関する問題です。日付の形はYYYY.MM.DDで全て同じで、全ての月の日数が28日に固定されています。規約に書いている月数を個人情報を保管し始めた日付と合わせると保管満了日が出ます。保管満了日と今日の日付を比べて保管満了日は過ぎた場合その個人情報のインデックス+1を保存してreturnすると解決です。
3. 解決方法
結果が個人情報保管順番に対した1次元配列であるため、個人情報を昇順で検索しながら日付が過ぎている個人情報の番号を枚列に入れれば良いのでソートする必要はないです。
Timestampと似たような方法で日付を比べ安い日数に変換して比べた後、日数が今日の日数より小さいとリストに保存する方式で解決しました。
terms配列にある値を名前と月数に分離して名前をKey、月数をValueに保存します。(termsMap)
privacies配列にある値を日付とterms名前に分離します。
terms名前をtermsMapから検索して月数を持って来た後、日付の日数+月数の日数を計算して満了日を計算します。
今日の日付の日数を計算します。
今日の日付の日数と満了日の日数を比べて、今日の日付の日数 ≥ 満了日の日数になる場合結果リストに保存します。
全ての反復が終了された時最終リストの配列を返します。
4. コード
public class Solution1 {
public static void main(String[] args){
Solution1 solution = new Solution1();
String today = "2022.05.19";
String[] terms = {"A 6", "B 12", "C 3"};
String[] privacies = {"2021.05.02 A", "2021.07.01 B", "2022.02.19 C", "2022.02.20 C"};
int[] result = solution.solution(today, terms, privacies);
for(int i : result){
System.out.print(i+", ");
}
}
public int[] solution(String today, String[] terms, String[] privacies) {
List<Integer> result = new ArrayList<>();
Map<String, Integer> termsMap = new HashMap<String, Integer>();
for(int i=0;i<terms.length;i++){
String name = terms[i].split(" ")[0];
String month = terms[i].split(" ")[1];
termsMap.put(name, Integer.parseInt(month));
}
for(int i=0;i<privacies.length;i++){
String date = privacies[i].split(" ")[0];
String term = privacies[i].split(" ")[1];
if(getTimestamp(date) + (termsMap.get(term) * 28) <= getTimestamp(today)){
result.add(i+1);
}
}
int[] answer = new int[result.size()];
for(int i=0;i<result.size();i++){
answer[i] = result.get(i);
}
return answer;
}
private int getTimestamp(String date){
String[] dateSplit = date.split("\\.");
int year = Integer.parseInt(dateSplit[0]);
int month = Integer.parseInt(dateSplit[1]);
int day = Integer.parseInt(dateSplit[2]);
return (year * 12 * 28) + (month * 28) + day;
}
}
Kommentarer