gpt4 book ai didi

javascript - 给定 X 个骰子输入,生成特定数字

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:39:44 24 4
gpt4 key购买 nike

我正在尝试想出一个解决方案,我需要掷一些骰子(所有骰子大小相同)并达到指定的数字。如果我有所有的验证以确保数字有效并且理论上可以达到预期的结果,有没有人有解决这个问题的好算法?请注意,它应该随机出现,而不仅仅是一条直线。

一些例子

roll 3 d6 and get 14 -> so it could output 5,3,6 or 6,6,2

roll 4 d20 and get 66 -> so it could output 16,14,19,17

我需要一个通用函数,它可以接受任意大小的骰子、任意数量的骰子以及所需的结果。

我最初的尝试如下,虽然这不会产生所需的输出(您现在可以忽略 mod,这也是为了允许修饰符)。此示例也缺少可实现所需输出的验证,但这不是问题的一部分。

let desired = 19
let mod = 0
let dm = desired - mod
let n = 5;// number of dice
let d = 6 // dice sides
let nums = []

for(i =0; i< n; i++) {
nums.push(Math.round(Math.random() * Math.round(d)) + 1)
}

let sum = nums.reduce((acc,val) => acc + val)


nums = nums.map(a => Math.round((a/sum) * dm))

let diff = dm - (nums.reduce((acc,val) => acc + val))
function recursive(diff) {
let ran = nums[Math.random() * Math.round(nums.length -1)]
if(nums[ran] + diff > d || nums[ran] + diff < 1) {
recursive(diff)
} else {
nums[ran] += diff
}
}
while(diff != 0) {
recursive(diff)
diff += diff < 0 ? 1 : -1;
}

alert(nums)

最佳答案

递归:

function foo(desired, rolls, sides, current) {
if (rolls === 0) {
return current.reduce((s, c) => s + c) === desired ? current : null;
}

const random = [];
for (let i = 1; i <= sides; i++) {
const randomIndex = Math.floor(Math.random() * (random.length + 1))
random.splice(randomIndex, 0, i);
}

for (const n of random) {
const result = foo(desired, rolls - 1, sides, [...current, n]);
if (result) {
return result;
}
}
}

console.log(foo(14, 3, 6, []))

非递归:

function foo(desired, rolls, sides) {
const stack = [[]];
while (stack.length) {
const current = stack.pop();
const random = [];
for (let i = 1; i <= sides; i++) {
const randomIndex = Math.floor(Math.random() * (random.length + 1));
random.splice(randomIndex, 0, i);
}

for (const n of random) {
if (current.length === rolls - 1) {
if (current.reduce((s, c) => s + c + n) === desired) {
return [...current, n];
}
} else {
stack.push([...current, n]);
}
}
}
}

console.log(foo(14, 3, 6));

具有最小内存消耗的非递归:

function foo(desired, rolls, sides) {
const currentIndexes = Array(rolls).fill(0);
const randoms = Array.from({ length: rolls }, () => {
const random = [];
for (let i = 1; i <= sides; i++) {
const randomIndex = Math.floor(Math.random() * (random.length + 1));
random.splice(randomIndex, 0, i);
}
return random;
})
while (true) {
if (currentIndexes.reduce((s, idx, i) => s + randoms[i][idx], 0) === desired) {
return currentIndexes.map((idx, i) => randoms[i][idx]);
}
for (let i = currentIndexes.length - 1; i >= 0; i--) {
if (currentIndexes[i] < sides - 1) {
currentIndexes[i] += 1;
break;
}
currentIndexes[i] = 0;
}
}
}

console.log(foo(14, 3, 6));

非递归解决方案,通过根据之前的滚动计算最后一次滚动,内存消耗最少并提高性能。

function foo(desired, rolls, sides) {
const currentIndexes = Array(rolls - 1).fill(0);
const randoms = Array.from({ length: rolls - 1 }, () => {
const random = [];
for (let i = 1; i <= sides; i++) {
const randomIndex = Math.floor(Math.random() * (random.length + 1));
random.splice(randomIndex, 0, i);
}
return random;
})
while (true) {
const diff = desired - currentIndexes.reduce((s, idx, i) => s + randoms[i][idx], 0);
if (diff > 0 && diff <= sides) {
return [...currentIndexes.map((idx, i) => randoms[i][idx]), diff];
}
for (let i = currentIndexes.length - 1; i >= 0; i--) {
if (currentIndexes[i] < sides - 1) {
currentIndexes[i] += 1;
break;
}
currentIndexes[i] = 0;
}
}
}

console.log(foo(66, 4, 20));

关于javascript - 给定 X 个骰子输入,生成特定数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53610101/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com