문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/150370

 

프로그래머스

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

programmers.co.kr

 

풀이

function solution(today, terms, privacies) {
    let answer = [];
    const todayTimestamp = new Date(today.replaceAll('.','-')).getTime();

    //terms 배열을 { termKind, duration} 형태로 변환
    const termsObj = {};
    terms.forEach(term => {
        const [termKind, duration] = term.split(' ');
        termsObj[termKind] = parseInt(duration);
    });

    //privacies를 순회하며 유효기간 비교
    privacies.forEach((privarcy, idx)=>{
        const [date, termKind] = privarcy.split(' ');
        const [year, month, day] = date.split('.').map(Number);

        //시작 날짜에서 유효기간 추가
        const duration = termsObj[termKind];
        const expirationDate = new Date(year, month-1+duration, day); //범위 넘어가면 알아서 변환함

        //오늘 날짜와 비교
        if(expirationDate.getTime() < todayTimestamp) {
            answer.push(idx+1);
        }
    });
    return answer; 
}

 

Date() 객체에 대해 많이 배울 수 있었다.

특히 month부분에 13을 넣으면 알아서 다음 년도로 계산한다는 점이 편리했다.

문제

원본 사이트: https://school.programmers.co.kr/learn/courses/30/lessons/258712

 

풀이

function solution(friends, gifts) {
    const friendsCount = friends.length;

    //선물 기록 (2차원 배열)
    const records = Array.from({length: friendsCount}, () => Array(friendsCount).fill(0));

    // 선물 지수 (1차원 배열)
    const giftScore = Array(friendsCount).fill(0);

    //선물 기록 및 선물 지수 계산
    gifts.forEach(gift => {
        //각 문자열을 배열로 변환(구조 분해)
        const [giver, receiver] = gift.split(' ');
        //각 이름 별 인덱스 값을 구하기
        const giverIndex = friends.indexOf(giver);
        const receiverIndex = friends.indexOf(receiver);
        //계산
        records[giverIndex][receiverIndex]++;
        giftScore[giverIndex]++;
        giftScore[receiverIndex]--;
    });

    //다음 달에 받을 선물 계산
    const nextMonthGifts = Array(friendsCount).fill(0);

    for(let i=0; i<friendsCount; i++){
        for(let j=i+1; j<friendsCount; j++){ 
            if(records[i][j] > records[j][i]){
                nextMonthGifts[i]++;
            } else if (records[i][j] < records[j][i]){
                nextMonthGifts[j]++;
            } else { // 같거나 기록이 0 -> 선물지수 비교
                if(giftScore[i] > giftScore[j]){
                    nextMonthGifts[i]++;
                } else if (giftScore[i] < giftScore[j]){
                    nextMonthGifts[j]++;
                }
            }
        }
    }

    return Math.max(...nextMonthGifts);
}

 

⭐️ 다음 달에 받을 선물을 계산할 때, j=i+1 부터 시작한 이유

1. 중복 계산 방지 ex. [i][j] 와 [j][i]

2. 대각선 위 요소만 검사(즉, 자기자신 부분은 제외)

=> 효율성: 이 방식으로 전체 비교 횟수를 거의 절반으로 줄일 수 있다. n명의 친구가 있다면, 총 비교 횟수는 n(n-1)/2가 된다.

 

+ Recent posts