Index and Search (2021 Kakao Blind Recruitment)

Task

https://programmers.co.kr/learn/courses/30/lessons/72412;

My Solution

referenced from:

  1. https://velog.io/@alvin/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4-%EC%88%9C%EC%9C%84-%EA%B2%80%EC%83%89-Javascript
  2. https://12bme.tistory.com/120
function solution(info, query) {
    let answer = [];
    // store every possible combination that every info can match to
    let combinations = {};
    const getCombinations = (arr, score, init) => {
        let spec = arr.join('');
        let value = combinations[spec];
        
        // add score to combination object
        if (value) {
            combinations[spec].push(score);
        } else {
            combinations[spec] = [score];
        }
        
        // recursive function, to loop through every possibility
        for (let i = init; i < arr.length; i++) {
            let temp = [...arr];
            temp[i] = '-';
            getCombinations(temp, score, i+1);
        }
    }
    
    // split criteria and score
    info.map(x => {
        let array = x.split(' ');
        let score = array.pop() * 1;
        getCombinations(array, score, 0);
    })
    
    // sort each combination's score in ascending order to use lower bound
    for (const key in combinations) {
        combinations[key] = combinations[key].sort((a,b) => a - b);
    }
    
    // loop through query
    for (const x of query) {
        let q = x.replace(/ and /g, ' ').split(' ');
        let score = q.pop() * 1;
        q = q.join('');
        let match = combinations[q];
        
        // if the combination exists, find lower bound to get scores
        if (match) {
            let start = 0;
            let end = match.length;
            while(start < end) {
                let mid = Math.floor((start + end) / 2);
                if(score > match[mid]) {
                    start = mid + 1;
                } else {
                    end = mid;
                }
            }
            // push matching score length to answer
            answer.push(match.length - start);
        } else {
            answer.push(0);
        }        
    }
    
    
    return answer;
}