[프로그래머스] 2024 KAKAO WINTER INTERNSHIP - 가장 많이 받은 선물

Dodam·2024년 1월 10일
1
post-thumbnail

문제 요약

두 사람이 선물을 주고 받은 기록이 있다면,
둘 중에 더 많이 준 사람이 선물을 받는다.

두 사람이 선물을 주고 받은 기록이 없거나 or 주고 받은 수가 같다면
선물 지수가 큰 사람이 작은 사람에게 받는다.

선물 지수 = 준 선물의 수 - 받은 선물의 수

만약 선물 지수도 같다면 선물을 주고 받지 않는다.

제한사항

// friends는 길이가 10이하인 문자열, 알파벳 소문자
2 <= friends = 친구들 수 <= 50
// friends의 원소로, 'a b'의 형태. (각각 '준 사람' '받은 사람'을 의미)
1 <= gifts <= 10,000

선물을 가장 많이 받을 친구의 선물 수를 return

풀이 정리

dstData 객체는 각 친구들 간의 선물 교환 횟수를 저장한다.
이중 중첩된 객체의 형태를 가지며, 각각의 친구는 자기 자신과 다른 친구들에 대한 정보를 가지고 있다.

friends 배열 기반으로 dstData 객체를 초기화한다.
각 친구에 대해 자기 자신과 다른 친구들 간의 선물 교환 횟수를 나타내는 정보를 설정한다.

gifts 배열을 순회하며 선물 교환 기록을 파싱하고,
dstData에 해당 정보를 업데이트한다.
각각의 선물 교환에 대해 선물을 주는 쪽은 선물 지수 증가,
받는 쪽은 선물 지수를 감소 시킨다.

Object.entries(dstData)를 사용하여 dstData 객체를 순회하면서
각 친구에 대한 선물 교환 정보를 확인한다.

참고

선물 지수(Gift Index)
: 선물을 주거나 받은 횟수 등을 기반으로 한
개인 또는 그룹의 선물 관련 활동에 대한 측정 지표
예) 어떤 사람이 선물을 자주 주거나 많이 받으면 선물지수가 높아짐

선물 계수(Gift Coefficient)
: 선물을 얼마나 자조 주고 받았는지를 나타내는 지표로,
두 사람 간의 상호작용을 특정 방식으로 측정
예) 두 사람 간의 선물계수가 높을수록 서로에게 자주 선물을 주고 받음

DST(Dialogue State Tracking)
: 대화의 상황을 추적하는 작업

문법 정리

Object.entries()
Object.entries() 메서드는 for...in과 같은 순서로 주어진 객체 자체의
enumerable 속성 [key, value] 쌍의 배열을 반환한다.
(for-in 루프가 다른 점은 프로토 타입 체인의 속성도 열거한다.)

Object.entries()에 의해 반환된 배열(array)은 순서가 없다.
따라서 다음과 같이 정렬을 먼저 하는 것이 좋다.
Object.entries(obj).sort((a, b) => b[0].localeCompare(a[0]));

JavaScript 코드

/*
// 친구 정보, 선물 정보 기반으로 dstData라는 데이터를 파싱한다.
// 파싱된 dstData의 타입은 다음과 같다.
interface friendsGift {
  [key: string]: {
    [key: string]: number | number[];	// 이름이 같으면 number, 다르면 number[]
  }
}
*/

function solution(friends, gifts) {
  let answer = 0;
  let dstData = {};
  
  // dstData 초기화
  friends.forEach(outerName => {
    dstData[outerName] = {}
    friends.forEach(innerName => {
      if(outerName !== innerName) {	 // 이름이 같지 않으면 [준 개수 0, 받은 개수 0]으로 초기화
        dstData[outerName][innerName] = [
          0,	// 준 개수
          0,	// 받은 개수
        ]
      }
      // 이름이 같은 경우, 선물 지수를 0으로 초기화
      else {
        dstData[outerName][innerName] = 0
      }
    })
  })

  
  // dstData 파싱
  gifts.forEach(gift => {
    [
      from,	 // 선물 준 사람
      to	 // 선물 받은 사람
    ] = gift.split(' ')
    dstData[from][from] += 1	// 선물 준 사람의 선물 지수 증가
    dstData[to][to] -= 1	// 선물 받은 사람의 선물 지수 감소
    
    // 선물 계수 계산
    dstData[from][to][0] += 1	// A가 B에게 얼마나 많은 선물을 줬는지
    dstData[to][from][1] += 1	// B가 A에게 얼마나 많은 선물을 받았는지
  })
  Object.entries(dstData).forEach(([fromName, giftDatas], index) => {
    tempAnswer = 0;
    Object.entries(giftDatas).forEach(([toName, giftData], index) => {
      
      // 준 사람과 받은 사람의 이름이 다른 경우
      if(fromName !== toName) {
        const [
          give,	// 선물 준 사람
          receive	// 선물 받은 사람
        ] = [...giftData]

        // 선물 준 사람의 개수가 더 많은 경우
        if(give > receive) {
          // 정답 증가
          tempAnswer += 1
        }
        
        // 선물 준 사람과 받은 사람의 개수가 같을 경우
        else if(give === receive) {
          // 선물 지수 비교
          // 준 사람의 선물 지수가 큰 경우에만 정답 증가
          if(dstData[fromName][fromName] > dstData[toName][toName]) {
            tempAnswer += 1
          }
        }
      }
    })
    // 정답 업데이트
    answer = Math.max(answer, tempAnswer)
  })
  return answer;
}
profile
⏰ Good things take time

0개의 댓글