Skip to content

Instantly share code, notes, and snippets.

@fronterior
Last active September 26, 2021 15:53
Show Gist options
  • Save fronterior/7bf0424ff4c47c05c2d48523b412947f to your computer and use it in GitHub Desktop.
Save fronterior/7bf0424ff4c47c05c2d48523b412947f to your computer and use it in GitHub Desktop.
List all cases in which M of the numbers from 1 to N are selected without overlapping. If the order is different, even the same value is treated as different cases. (1 <= M <= N)
const [N,M] = [5, 2];
const contextStack: number[][] = [];
const stack = Array.from({length: N}, (_,i) => i + 1);
const result: number[] = [];
let target: number;
let isEnd = false;
while (1) {
// When one case is completed
if (result.length === M) {
console.log(result.join(' '));
result.pop();
continue;
}
// If run out of stack, go back to the previous context.
while (!stack.length) {
// If don't have both the remaining stack and the context stack, it's over.
if (!stack.length && !contextStack.length) {
isEnd = true;
break;
}
stack.push(...contextStack.pop() as number[]);
result.pop();
}
if (isEnd) break;
// The currently selected number.
target = stack.shift();
// Pass the number that was already chosen.
if (!result.includes(target)) {
result.push(target);
// Save context so that you can go back if you don't choose all M of Numbers.
if (result.length !== M) {
contextStack.push(stack.splice(0));
// Stack reset.
stack.push(...Array.from({length: N}, (_,i) => i + 1));
}
}
}
// result console.log
// 1 2
// 1 3
// 1 4
// 1 5
// 2 1
// 2 3
// 2 4
// 2 5
// 3 1
// 3 2
// 3 4
// 3 5
// 4 1
// 4 2
// 4 3
// 4 5
// 5 1
// 5 2
// 5 3
// 5 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment