我正在尝试编写一种递归生成所有彩票组合的算法。
这是一个非递归变量,可用于获得C(max,6)。例如C(7,6)
let min = 1;
let max = 7;
let lotteryNum = 0;
let outputString = [];
for (let a = min; a <= max - 5; a++) {
for (let b = a + 1; b <= max - 4; b++) {
for (let c = b + 1; c <= max - 3; c++) {
for (let d = c + 1; d <= max - 2; d++) {
for (let e = d + 1; e <= max - 1; e++) {
for (let f = e + 1; f <= max; f++) {
lotteryNum++
outputString.push(format([a, b, c, d, e, f]) +
" <= " + lotteryNum + "\n");
}
}
}
}
}
}
function format(n) {
n.forEach((v, i) => {
n[i] = v < 10 ? '0' + v : '' + v;
});
return n.join(' ');
}
console.log(outputString.join(''));
输出
01 02 03 04 05 06 <= 1
01 02 03 04 05 07 <= 2
01 02 03 04 06 07 <= 3
01 02 03 05 06 07 <= 4
01 02 04 05 06 07 <= 5
01 03 04 05 06 07 <= 6
02 03 04 05 06 07 <= 7
我尝试写一个递归算法,所以我可以得到C(最大值,长度),因为上面硬编码为C(最大值,6),并提出如下,但我不知道如何得到params需要像上面那样构建组合字符串。
function doRec(min, max, offset) {
if (offset >= 0) {
for (let a = min; a <= max - offset; a++) {
doRec(a + 1, max, offset - 1);
}
} else {
// how to create outputString params?
}
}
doRec(1, 7, 5);
奖金问题,是否有直接的方式将彩票组合数学转换为整数,反之亦然,而不是使用上面的暴力方法?
e.g。从上面的输出
01 02 03 04 05 06 <=> this is lottery number 1
02 03 04 05 06 07 <=> this is lottery number 7
so something like getLotteryNumber('02 03 04 05 06 07') returns 7 in this case.
答案 0 :(得分:5)
我正在尝试编写一种递归生成所有彩票组合的算法。
内存高效的生成器功能非常适合这项任务:
// Generate all k-combinations of numbers [1..n] without repetition:
function* combinations(n, k) {
if (k < 1) {
yield [];
} else {
for (let i = k; i <= n; i++) {
for (let tail of combinations(i - 1, k - 1)) {
tail.push(i);
yield tail;
}
}
}
}
// Example:
for (let combination of combinations(7, 6)) {
console.log(combination);
}
答案 1 :(得分:0)
奖金问题,有没有一种直接的方法可以将彩票组合数学转换为整数?
function getLotteryNum(combination, max = 49) {
const combinationLength = combination.length;
const Σ = (currentNum, prevNum = 0, pos = 1) => {
let sum = 0;
const Δk = combinationLength - pos;
while (currentNum > prevNum) {
let Δn = max - currentNum;
sum += mathjs.combinations(Δn, Δk);
currentNum--;
}
return sum;
}
const ΣΣ = (acc, num, ii, comb) =>
acc + (comb.length - ii === 1 ?
comb.slice(-2).reduce((acc, num) => num - acc, 0) :
Σ(num - 1, ii > 0 ? comb[ii - 1] : 0, ii + 1));
return combination.reduce(ΣΣ, 0);
}
//e.g.
console.log(getLotteryNum([44, 45, 46, 47, 48, 49])); // 13983816
console.log(getLotteryNum([1, 2, 3, 4, 5, 6])); // 1
console.log(getLotteryNum([9, 26, 31, 36, 38, 44])); //10108381