코드 풀이

메뉴 리뉴얼

SammyK 2022. 4. 4. 16:19

 

풀이1번:

 

const combinations = function(menu, order, cnt, idx, prev) {
    if (prev.length === cnt) {
        let curStr = prev.sort().join('');  // 기존 주문 배열 내 원소가 주문 횟수만큼 있다면 원소들 문자로 생성

        // 메뉴 객체에 기존 메뉴가 존재한다면 해당 메뉴 주문 횟수에 +1, 아니라면 새로 생성
        if (menu.has(curStr)) menu.set(curStr, menu.get(curStr)+1);
        else menu.set(curStr, 1);
    }

    // 기존 인덱스부터 문자열 하나씩 추가한 후 조합 재귀
    for (let i = idx; i < order.length; i++) {
        combinations(menu, order, cnt, i+1, [...prev, order[i]]);
    }
}

function solution(orders, course) {
    let menu = new Map();   // Map객체 생성: [['문자열 조합', 주문 횟수], ['문자열 조합', 주문 횟수], ...]

    // 조합으로 주문 횟수에 따른 menu객체 완성시키기
    orders.map(order => {
        course.map(cnt => combinations(menu, order, cnt, 0, []));
    });

    // 주문 횟수 2회 이상인 메뉴들로 필터링
    menu = [...menu.entries()].filter(elem => elem[1] >= 2).sort((a, b) => b.length - a.length);

    let result = [];
    course.map(cnt => {
        let max = 0;
        let tmp = menu.filter(([str, num]) => {
            if (max < num && str.length === cnt) max = num;
            return str.length === cnt;
        })
        tmp.filter(x => x[1] === max).map(x => result.push(x[0]));
    })

    // return 시 오름차순
    return result.sort();
}

prev 는 order 의 문자열을 하나하나로 쪼개어 만들어진 모든 조합.

처음엔 아무것도 없으니 [] 빈 배열, 그후 주문 order[i] 번의 문자를 붙여 체크.


이중 course 만큼 길이가 같은것들만 curStr 에 저장. = 모든 콤비네이션들을 붙이고 저장.


그리고 menu 객체에 그 콤비네이션이 있나 비교하고 있으면 카운트 1 올려줌.


그리고 위에 보시다 싶이 다음 콤비네이션으로 비교하는 재귀함수


그리곤 메뉴에서 주문 횟수가 2이상인것만으로 filter 해줌.


후에 course 길이 [2,3,4] 대로 필터링하여 .map 해줌.


그리고, 제일 주문이 많이 된것들로 필터링을 합니다.


그리고 주문들만 result [] 배열에 push 해주고. 그후 오름차순으로 정렬을 해주고 그 값을 리턴 해줍니다.

 

 

풀이 2:

const combination = (arr, num) => {
    let result = [];
    //num이 1이 될때 까지 재귀함수를 통해 반복한다.
    if (num === 1) return arr.map(e => [e]);
    for (let i = 0; i < arr.length; i++) {
        let rest = arr.slice(i+1)
        let combinations = combination(rest, num-1)
        //map함수를 통해 [i, + combinations[x]]를 합쳐준다.
        let combiArr = combinations.map(x => [arr[i], ...x])
        //result에 combiArr을 이어 붙여준다.
        result.push(...combiArr)
    }
    return result

}

function solution(orders, course) {
    //d : 메뉴의 조합
    const d = new Map()
    //m : 몇가지 조합인지
    const m = new Map();

    for (const order of orders) {
        for (const n of course) {
            for (let tmp of combination(order.split('').sort(), n)) {
                //배열을 문자열로 변환
                tmp = tmp.join('')
                //d가 tmp를 가지고 있지 않으면 tmp : 0 삽입
                if (!d.has(tmp)) d.set(tmp, 0);
                //m이 n을 가지고 있지 않으면 n : 2 삽입
                if (!m.has(n)) m.set(n, 2);
                //d[tmp]의 값을 가져와서 1을 더함
                const c = d.get(tmp) + 1
                //m[n]의 값을 가져옴
                const x = m.get(n)
                //tmp의 개수 초기화
                d.set(tmp, c)
                //x와 c를 비교해서 더큰 값으로 초기화
                m.set(n, x > c ? x : c)
            }
        }
    }
    //d의 요소에서 filter함수를 통해 value값이
    //m 요소에서 d의 key값의 길이와 같은 값만 필터링 한 후
    //map함수를 통해 key값만 추출한뒤 정렬
    return Array.from(d.entries()).filter(([v,c]) => c == m.get(v.length)).map(([v,c]) => v).sort()
}

 

'코드 풀이' 카테고리의 다른 글

피보나치 수  (1) 2022.04.18
완전탐색 소수찾기  (0) 2022.04.12
기능 개발  (0) 2022.03.30
124 나라의 숫자  (0) 2022.03.29
멀쩡한 사각형  (0) 2022.03.28