본문 바로가기

알고리즘 문제풀이

[프로그래머스] 2021 카카오 공채 - 순위 검색

오늘 푼 문제

 

3. 순위 검색/ Lv.2 / 시간 : 128분 (타임오버 이게 lv2라고????????????)

programmers.co.kr/learn/courses/30/lessons/72412

 

코딩테스트 연습 - 순위 검색

["java backend junior pizza 150","python frontend senior chicken 210","python frontend senior chicken 150","cpp backend senior pizza 260","java backend junior chicken 80","python backend senior chicken 50"] ["java and backend and junior and pizza 100","pyt

programmers.co.kr

 

function solution(info, query) {
    var answer = [];
    let list = info.map(str=>str.split(' '))
    let hash = list.reduce((h,arr)=>{
        arr.reduce((acc,cur,i)=>{
            if(i===4) acc.forEach(key=>{
                if(h[key]) h[key].push(cur*1);
                else h[key] = [cur*1];
            })
            else acc = [...acc.map(s=>s+cur),...acc.map(s=>s+'-')];
            return acc;
        },[""])
        return h;
    },{});
    Object.values(hash).forEach(arr=>arr.sort((a,b)=>a-b));
    
    let getCount = (arr,num)=>{
        let len = arr.length;
        let [s,l] = [0,len];
        let value;
        while(true){
            if(s>l) return value;
            let mid = Math.floor((s+l)/2);
            if(arr[mid]<num){
                s = mid+1;
            }else{
                value = len - mid;
                l = mid-1;
            } 
        }
    };

    answer = query.map(s=>{
        let value = s.match(/\d/g).join('')*1;
        let str = s.replace(/\d/g,"").replace(/ and |\s/g,"");
        let target = hash[str];
        if(target){
            return getCount(target,value);
        }else return 0;
    })
    return answer;
}

 

헤맸던 부분

1. info값을 저장하는 로직을 아예 이상하게 세워버리는 바람에 시간을 너무 많이 허비했다. 어떻게 하려고 했냐면 

  • 개발언어는 cpp, java, python 중 하나입니다.
  • 직군은 backend, frontend 중 하나입니다.
  • 경력은 junior, senior 중 하나입니다.
  • 소울푸드는 chicken, pizza 중 하나입니다.

이 상황에서 문자열로 주어진 info를 모두 중첩된 객체로 만들었음.

ex) {java : {backend : { junior: { chicken: {pizza: { 150 :1, 250 :2, ... }}}, frontend:{ ... }}, cpp:{ ... }, ... }

그리고 주어진 query를 파싱해 키값을 하나하나 따라간 다음 마지막 키값(점수)에 대해 크기 비교 후 카운트를 하려 했으나 복병이 있었으니.

  • '-' 표시는 해당 조건을 고려하지 않겠다는 의미입니다.

-가 주어진 경우 하위 객체를 모두 다음 단계로 넘겨줘야 하는데 이게 문제가 됐다. 객체를 합치려 해도 중복 키값에 대해 데이터를 덮어쓰게 되고, 배열형으로 전달하면 다른 단계에서 객체로 넘겨주는 부분을 또 수정을 해야하고 -가 중복으로 나오는 상황에는 배열또한 중복으로 넘어가게 되므로 점점 로직이 우주로 가기 시작함. 60분 정도를 허비하고 다른 접근 방식을 사용했다.

 info를 굳이 중첩 객체로 사용하기보다는 조건을 모두 합쳐서 하나의 문자열로 만들어 key값으로 하고, 점수를 value로 하는 심플한 객체로 생성함. 이 때 info해시를 생성 할 때 아예 -에 대한 고려를 해줬다. 총 네 가지 경우에 대해 값 또는 -를 모두 만들어줘서 하나의 info문에 대해 총 16가지 경우가 생김 

ex) java, frontend, junior, chicken, 150의 개발자는 "javafrontendjuniorchicken" : [150], "-frontendjuniorchicken" : [150], "java-juniorchicken" : [150], ... 등의 객체값을 생성함.

 

2. 이렇게 값도 다 파싱했겠다 query 쫓아가면서 점수 추출하는 건 가볍게 filter와 length를 사용했으나 어림도 없지 가볍게 효율성 테스트에서 나가리를 맞아버림~ㅋㅋㅋ; 점수들이 저장된 value 배열을 정렬하고 이진탐색을 해줘야 했다...

 

단순 구현문제라고 좋아했는데 은근 신경 쓸 것도 많고 첨부터 머리 제대로 안 굴리면 시간 어마어마하게 잡아먹는 나쁜 친구였다 흑흑.