코딩테스트

[JS] 2022 KAKAO BLIND RECRUITMENT > 신고 결과 받기

차차한 2022. 8. 26. 10:48

계속 풀어보려고 노력했던 문제였는데 드디어 풀었다

문제 이해하는 것부터 힘들었던 ..ㅠ

report에서 "muzi frodo"일 때 무지가 프로도를 신고하고 "apeach frodo"일 때 어피치가 프로도를 신고한다는 뜻

k이상 신고당하면 정지가 된다.

정지가 됐을 때 신고한 회원에게 메일을 발송하는데, 이때 각 회원이 몇 번의 메일을 받는지를 리턴해야 한다.. 

function solution(id_list, report, k) {

    // 신고 내역 중복제거
    report = [...new Set(report)].map(v => v.split(" ")); 

    //신고한 사람
    //var b = report.map((v,i)=>report[i][0]);

    //신고당한 사람
    var a = report.map((v,i)=>report[i][1]);

    var map = new Map();
    a.forEach((v,i)=>{
        map.set(a[i], (map.get(a[i]) || 0) + 1);
    })

     //신고횟수 넘은 사람
    var arr = [];
    for (let [key, value] of map) {

        if(value >= k){
            arr.push(key);
        }
    }

    var answer = [];
    for(var i = 0; i < report.length; i++){
        for(var j = 0; j < arr.length; j++){
            if(report[i][1] == arr[j]){
                answer.push(report[i][0])
            }
        }
    }

    var c = new Map();

    for(var i = 0; i < id_list.length; i++){
        c.set(id_list[i], 0);
    }

    for(var i = 0; i < answer.length; i++){

        c.forEach((v,k)=>{
            if(k == answer[i]){
                c.set(k, v + 1);
                return;
            }
        })        
    }

    var arr2 = [];
    for(var i = 0; i<id_list.length; i++){
        arr2.push(c.get(id_list[i]))
    }

    return arr2;
}

내가 푼 풀이..

다행히 한 번에 통과는 됐지만 몇 테스트케이스는 풀이시간이 오래걸렸다.

report = [...new Set(report)].map(v => v.split(" "));

먼저 신고내역(report)를 set객체에 담아 중복된 신고내역을 제거해줬다. 입출력 예시 2번처럼 라이언이 콘을 신고한 내역이 4번이나 되기 때문에 중복을 제거해줘야 한다.

중복이 제거된 set 객체를 다시 배열에 담고, 반복을 돌려서 인덱스 내 문자열을 split으로 분리해준다.

그러면 "muzi frodo"가 ["muzi", "frodo"]가 된다. 이렇게 하면 0번 인덱스는 신고한 사람, 1번 인덱스는 신고당한 사람으로 정해진다.

//신고당한 사람
var a = report.map((v,i)=>report[i][1]);

var map = new Map();
a.forEach((v,i)=>{
    map.set(a[i], (map.get(a[i]) || 0) + 1);
})
//Map { 'frodo' => 2, 'neo' => 2, 'muzi' => 1 }

신고당한 사람은 따로 a배열에 담아줬다.

그리고 map객체를 이용해서 신고를 몇 번 당했는지를 입력했다.

key에는 신고당한 사람 이름, value에는 신고당한 횟수가 들어간다.

 //신고횟수 넘은 사람
var arr = [];
for (let [key, value] of map) {

    if(value >= k){
        arr.push(key);
    }
}
//[ 'frodo', 'neo' ]

신고 횟수가 넘은 사람도 따로 배열에 담아줬다.

for of를 이용해 map을 반복하고 value 즉 신고당한 횟수가 k 이상이면 arr배열에 key(신고당한 사람 이름)을 담아줬다.

var answer = [];
    for(var i = 0; i < report.length; i++){
        for(var j = 0; j < arr.length; j++){
            if(report[i][1] == arr[j]){
                answer.push(report[i][0])
            }
        }
    }
//	[ 'muzi', 'apeach', 'frodo', 'muzi' ]

이중 for문을 돌려서 신고메일을 받을 사람의 이름을 answer 배열에 담아줬다.

arr배열에 이름이 있으면 k 이상으로 신고를 당한 거니까 그 조건일 때만 answer에 push

--다시 보니 굳이 이중for문을 돌릴 필요가 없었다. 위에서 a배열에 이미 신고당한 사람만 모아놨었으니까...

var c = new Map();

    for(var i = 0; i < id_list.length; i++){
        c.set(id_list[i], 0);
    }
    
    for(var i = 0; i < answer.length; i++){

        c.forEach((v,k)=>{
            if(k == answer[i]){
                c.set(k, v + 1);
                return;
            }
        })        
    }
// Map { 'muzi' => 2, 'frodo' => 1, 'apeach' => 1, 'neo' => 0 }

회원별 메일을 몇 번 받는지 체크하기 위해 먼저 id_list배열을 map객체에 담아줬다.

그리고 c의 key값(회원이름)이 신고메일받을사람 배열에 있으면 value를 1씩 올려줬다.

var arr2 = [];
    for(var i = 0; i<id_list.length; i++){
        arr2.push(c.get(id_list[i]))
    }
// [ 2, 1, 1, 0 ]

마지막으로 배열 형태로 리턴을 해야해서 arr2배열에 map에 저장된 value를 가져와 담아줘서 리턴해줬다.


function solution(id_list, report, k) {
    let reports = [...new Set(report)].map(a=>{return a.split(' ')});
    let counts = new Map();
    for (const bad of reports){
        counts.set(bad[1],counts.get(bad[1])+1||1)
    }
    let good = new Map();
    for(const report of reports){
        if(counts.get(report[1])>=k){
            good.set(report[0],good.get(report[0])+1||1)
        }
    }
    let answer = id_list.map(a=>good.get(a)||0)
    return answer;
}

다른 사람 풀이

report를 set객체에 담고 문자열을 나눠 다시 배열에 담은 것은 동일하다.

 

다음 map객체를 선언해주고 reports(신고내역 중복제거)를 반복해 map객체에 바로 담아줬다

key에는 신고당한 사람 이름, value에는 신고당한 횟수를 넣어줬다.

 

다른 map객체를 선언해주고 신고내역(reports)를 돌려 신고당한사람(counts)에서 k이상으로 신고당한 사람만 good객체에 담아준다.

 

마지막으로 id_list를 반복해 신고당한 사람 객체에 이름 key를 넣어 그 value를 가져와 배열에 담아줬다..

다른 사람의 풀이를 보고 느낀 점,.

나는 map에서 key, value를 제대로 사용하지 못 해서 쓸데없이 반복한 코드가 많다.

나도 set, map을 사용했지만 코드가 복잡해 가독성이 떨어지고 효율도 낮다.

문제 풀기 전에 어떤 식으로 풀으면 좋을지 먼저 생각을 하고 풀어야겠다..