끄적끄적

[Programmers] 가장 많이 받은 선 풀이(JS) 본문

Programmers

[Programmers] 가장 많이 받은 선 풀이(JS)

2024. 1. 10. 20:18

 

현재 프로그래머스 Lv 1임에도 불구하고 정답율이 22%를 기록하고 있길래, 도전 의식이 생겨서 도전 해본 문제이다.

 

문제를 간단히 요약하자면,

friends라는 string array를 받고, 

gifts라는 string array를 받는데 좌측은 선물을 준사람, 우측은 선물을 받는 사람이다.

이때 위의 조건으로 각 friend 중 다음달에 가장 많은 선물을 받은 사람을 구하는 것이다.

 

이 문제는 개인적으론 처음부터 어떤 자료구조를 사용하여 선물받았던 기록, 선물점수, 등을 저장해놓고 사용하는지가 관건인 것 같았다.

나는 다음과 같이 데이터 구조를 잡았다.

person = {
	name: {
        'name': name,
        'send: {
            // 현재 friend가 준 사람과 개수
            '철수': 2,
            '영미': 0,
            ...
        },
        'receive': {
        	// send와 같은 구조
        },
        'nextReceive': 0, 	// 다음달 받을 선물 개수를 저장해놓을 변수
        'point': 0			// 선물점수를 계산하여 저장해놓을 변수
    },
	...
}

 

그리고 gifts를 반복하여, 공백으로 split 한 후 선물 점수와 send, receive 변수를 만들어 채웠다.

gifts.forEach(data => {
    let d = data.split(' ');
    let sender = d[0];
    let receiver = d[1];
    person[sender].send[receiver]++;
    person[sender].point++;
    person[receiver].receive[sender]++;
    person[receiver].point--;
})

 

그 다음으로는 다음달 선물받는 조건들을 설정하여 개수를 정하는 과정이다.

for(let i=0; i<friends.length-1; i++){
    for(let k=i+1; k<friends.length; k++){
            if(
                person[friends[i]].send[friends[k]] > person[friends[k]].send[friends[i]]
            ) {
                person[friends[i]].nextReceive++;
            } else if (
                person[friends[i]].send[friends[k]] < person[friends[k]].send[friends[i]]
            ) {
                person[friends[k]].nextReceive++;
            } else if (
                person[friends[i]].send[friends[k]] === person[friends[k]].send[friends[i]]
            ) {
                if(person[friends[i]].point > person[friends[k]].point){
                    person[friends[i]].nextReceive++;
                } else if (person[friends[i]].point < person[friends[k]].point){
                    person[friends[k]].nextReceive++;
                }
            }
    }
}

 

주고 받은 사람만이 조건이 되는 것이 아니라 모든 인원이 서로의 경우를 따져 보기 때문에 2중 for문으로 nC2조합을 모두 따져봐야 한다.

person[friends[i]] 가 A, person[friends[k] 를 B 라고 했을때, A 가 B에게 준(send 의 값) 선물 보다 B가 A에게 준 선물이 많다면 B가 하나 받고, 아니면 A가 받고,

만약 동일하게 주고 받았다면(서로 안주고 받았을 경우도 포함된다 0으로), 선물점수를 따져 계산했다.

 

 

결과 코드

function solution(friends, gifts) {
    var answer = 0;
    let person = {};
    friends.forEach(name => {
        person[name] = {
            send: {},
            receive: {},
            nextReceive: 0,
            point: 0
        };
        friends.forEach(name2 => {
            person[name].send = {
                ...person[name].send,
                [name2]: 0
            }
            person[name].receive = {
                ...person[name].receive,
                [name2]: 0
            }
        })
    })
    
    // 선물지수가 클수록 선물을 많이 준것
    gifts.forEach(data => {
        let d = data.split(' ');
        let sender = d[0];
        let receiver = d[1];
        person[sender].send[receiver]++;
        person[sender].point++;
        person[receiver].receive[sender]++;
        person[receiver].point--;
    })
    
    for(let i=0; i<friends.length-1; i++){
        for(let k=i+1; k<friends.length; k++){
            if(
                person[friends[i]].send[friends[k]] > person[friends[k]].send[friends[i]]
            ) {
                person[friends[i]].nextReceive++;
            } else if (
                person[friends[i]].send[friends[k]] < person[friends[k]].send[friends[i]]
            ) {
                person[friends[k]].nextReceive++;
            } else if (
                person[friends[i]].send[friends[k]] === person[friends[k]].send[friends[i]]
            ) {
                if(person[friends[i]].point > person[friends[k]].point){
                    person[friends[i]].nextReceive++;
                } else if (person[friends[i]].point < person[friends[k]].point){
                    person[friends[k]].nextReceive++;
                }
            }
        }
    }
    

    let result = Object.entries(person).sort((a, b) => a[1].nextReceive - b[1].nextReceive);
    answer = result[result.length-1][1].nextReceive;

    
    
    return answer;
}

 마지막 처리는 다음달 선물받을 개수가 가장 많은 사람 (nextReceive가 가장 큰사람)을 색출하기 위해 sort 하여, 맨뒤에있는 사람을 추출하는 과정이다. 

Comments