개업 이래로 항상 승승장구하는 '승승장구 치킨집'의 비결은 소스에 있다. 수많은 타사 브랜드 치킨집들이 승승장구 치킨집의 소스 비결을 알아내려고 했으나 빈번히 포기했다.
그 이유는 5대째 내려오는 '비밀의 승승장구 치킨 소스 비율 레시피'는 70억 인구 중 사장님만 알고 있기 때문이다. 최근, 누리꾼 사이에서 이 레시피의 일부분을 발췌했다는 소문을 듣게 되었다.
그 소문은 다음과 같다.
N 가지의 재료 중에 단 M 가지만을 사용하여 조합한 모든 경우의 수 중 하나이다.
재료는 0과 1로만 이루어진 숫자로 암호화가 되어 있고, 항상 1로 시작하며 복호화를 할 수 없다.
재료의 순서에 따라 맛이 달라지기 때문에, 재료를 넣는 순서가 다르다면 다른 레시피이다.
이 소문을 참고하여 '비밀의 승승장구 치킨 소스'가 될 수 있는 경우의 수를 모두 반환하는 함수를 작성하세요.
Number 타입의 1 이상 stuffArr 길이 이하의 자연수
재료를 선택할 수 있는 수를 뜻합니다.
ex) 2
먼저, 상한 재료를 필터링후, 재귀를 수행합니다.
재귀를 수행할 때마다, 이미 선택한 재료는 골라선 안되기 때문에 순열로 접근해야 합니다.
순열은 이전에 업로드한 중복 순열과 거의 유사합니다.
다른 점은, 재귀의 인자로 전달하는 배열입니다.
재귀로 전달하는 배열은 이미 선택한 요소를 제외한 배열로 재할당해야합니다.
function newChickenRecipe(stuffArr, choiceNum) {
// 상한 재료를 필터링하여 새로운 배열로 리턴합니다.
let freshArr = stuffArr.filter((el) => String(el).slice(-3) !== "000");
const recur = function (arr, choiceNum) {
let result = [];
if (choiceNum === 1) return arr.map((hand) => [hand]);
// 재귀 함수는 중복 순열과 거의 동일합니다.
arr.forEach((hand, idx, arr) => {
const fixer = hand;
// 중복 순열과의 차이점
// 일반 순열은 이미 선택한 요소는 다시 선택할 수 없습니다.
// 필터링한 배열을 재귀의 인자로 전달합니다.
const restArr = arr.filter((_, index) => index !== idx);
const permuationArr = recur(restArr, choiceNum - 1);
const combineFixer = permuationArr.map((hand) => [fixer, ...hand]);
result.push(...combineFixer);
});
return result;
};
return recur(freshArr, choiceNum);
}
console.log(newChickenRecipe([1, 10, 1100, 1111], 2));