[프로그래머스] 🎁가장 많이 받은 선물

Chobby·2024년 2월 20일
1

Programmers

목록 보기
326/345

😀요점

  1. 준 선물 수, 받은 선물 수, 선물 지수를 담는 객체 생성
  2. 2중 반복을 통한 다음 달 선물 수 계산
  3. 선물을 주지도, 받지도 않은 사람이 있을 수 있음 (테스트 케이스 17, 19)
  4. 서로 선물 이력이 없는 경우, 선물 빈도까지 모두 같은 경우 두 경우 모두 선물 지수로 비교하여 더해야함

😎풀이

function solution(friends, gifts) {
    const giftDict = {}
    const nextMonthGift = {}
    // 준 선물 수, 받은 선물 수, 선물 지수 계산
    gifts.forEach(gift => {
        const [from, to] = gift.split(" ")
        if(giftDict[from]) {
            giftDict[from].giveList.push(to)
            giftDict[from].giveCount++
            giftDict[from].giftScore++
        } else {
            giftDict[from] = {
                giveCount: 1,
                giftScore: 1,
                takeCount: 0,
                giveList: [to]
            }
        }
        if(giftDict[to]) {
                giftDict[to].giftScore--
                giftDict[to].takeCount++
            } else {
                giftDict[to] = {
                    giftScore: -1,
                    takeCount: 1,
                    giveCount: 0,
                    giveList: []
                }
            }
    })
    // 1:1 매칭해서 누구에게 추가 선물이 주어질지 계산
    for(let i = 0; i < friends.length; i++) {
        const curFrom = friends[i]
        nextMonthGift[curFrom] = nextMonthGift[curFrom] ?? 0
        for(let j = i+1; j < friends.length; j++) {
            const curTo = friends[j]
            nextMonthGift[curTo] = nextMonthGift[curTo] ?? 0
            // 선물을 주지도, 받지도 않았을 경우 기록되지 않았을 수 있음
            if(!giftDict[curFrom]) {
                nextMonthGift[curTo]++
                continue
            } 
            if(!giftDict[curTo]) {
                nextMonthGift[curFrom]++
                continue
            }
            // 선물 이력으로 계산
            const fromIdx = giftDict[curFrom].giveList.indexOf(curTo)
            const toIdx = giftDict[curTo].giveList.indexOf(curFrom)
            if(toIdx < 0 && fromIdx < 0) {
                // 선물 지수로 계산
                const fromGiftScore = giftDict[curFrom].giftScore
                const toGiftScore = giftDict[curTo].giftScore
                if(fromGiftScore === toGiftScore) continue
                if(fromGiftScore > toGiftScore) nextMonthGift[curFrom]++
                else nextMonthGift[curTo]++
                continue
            }
            if(toIdx < 0 && fromIdx >= 0) {
                nextMonthGift[curFrom]++
                continue
            }
            if(toIdx >= 0 && fromIdx < 0) {
                nextMonthGift[curTo]++
                continue
            }
            // 선물 빈도로 계산
            const fromSum = giftDict[curFrom].giveList.reduce((acc, cur) => cur === curTo ? acc+1 : acc, 0)
            const toSum = giftDict[curTo].giveList.reduce((acc, cur) => cur === curFrom ? acc+1 : acc, 0)
            if(fromSum !== toSum) {
                let addGift = null
                if(fromSum > toSum) addGift = curFrom
                else addGift = curTo
                nextMonthGift[addGift]++
                continue
            }
            // 선물 지수로 계산
            const fromGiftScore = giftDict[curFrom].giftScore
            const toGiftScore = giftDict[curTo].giftScore
            if(fromGiftScore === toGiftScore) continue
            if(fromGiftScore > toGiftScore) nextMonthGift[curFrom]++
            else nextMonthGift[curTo]++
        }
    }
    
    return Math.max(...Object.values(nextMonthGift))
}
profile
내 지식을 공유할 수 있는 대담함

0개의 댓글