function solution(orders, course) {
let menu = {};
// 메뉴들을 조합으로 가져오는 함수
function combination(order, idx, len, prev) {
if (prev.length === len) {
let cur_key = prev.sort().join("");
if (cur_key in menu) {
menu[cur_key] += 1;
} else menu[cur_key] = 1;
return;
}
for (let i = idx; i < order.length; i++) {
combination(order, i + 1, len, [...prev, order[i]]);
}
}
//orders를 처음부터 끝까지 반복하면서
//course도 처음부터 끝까지 반복된다.
//그렇게 course 수에 맞는 조합들을 menu에 다 집어넣는다.
orders.map((order) => {
course.map((num) => combination(order, 0, num, []));
});
//result를 뽑아내기 위한 배열
let answer = [];
//course의 수에 맞춰 메뉴를 가져오면서
for (let i of course) {
/* menu의 경우 dictionary지만 Object.entries를 사용하면서
["AB", 1] 와 같은 배열로 추려지게된다.
이를 위해 course 길이인것만, 또 손님이 2번이상 시킨것만 골라서
그 중 최대 값이 몇인지를 갱신해준다.(max는 최대값인 배열만 뽑기위해)
그리고 마지막으로는 return으로 course와 "AB"와 같은 길이가 같은 것만
filter로 걸러온다. */
let max = 0;
let temp = Object.entries(menu).filter(([k, v]) => {
if (max < v && k.length === i && v > 1) max = v;
return k.length === i;
});
/* 마지막으로 아까 구했던 max값을 이용해 filter로 값을 다 가져온다.
현재 배열의 길이가 course만큼인 배열만 존재하고 그 중 max값은
중복이 존재할 수 있기 때문에, filter로 가져오며 마지막엔 answer에
push 해주면 된다. */
temp = temp
.filter(([k, v]) => {
return v === max;
})
.map(([k, v]) => answer.push(k));
}
// 사전순 정렬이 문제 조건.
return answer.sort();
}
* 재귀를 이용한 조합만 잘하면 나머지는 구현에 가까운 문제였다.
역시나 재귀에 약해서.. 머릿속에서 흐름을 생각하고 구현해도 안되었고,
손으로 그려가며 구현해도 안되어서 검색해보았고, 여러 방식중에 위의 방식이 내 입맛에 가장 맞았다.
이 문제의 코드는 생각보다 filter와 map 등의 깊이가 깊어서 주석으로 설명을 추가했다.