将数字拆分为4个随机数

Mik*_*Hrn 9 javascript

我想分成104个随机数的数组,但都不能0或不高于4.例如[1,2,3,4],[1,4,4,1][4,2,3,1].

我认为这是一个简单的问题,但由于某种原因,我无法想到如何做到这一点.如果有人有一些非常有帮助的指示!

编辑:这是我现在的代码,但我生成的总数低于10:

  let formation = [];
  let total = 0;

   for (let i = 0; i < 4; i ++) {
    if (total < 9) {
      formation[i] = Math.floor(Math.random() * 4) + 1; 
    } else {
      formation[i] = 1;
    }
  }
Run Code Online (Sandbox Code Playgroud)

Nin*_*olz 30

您可以创建所有可能的组合并选择一个随机数组.

function get4() {

    function iter(temp) {
        return function (v) {
            var t = temp.concat(v);
            if (t.length === 4) {
                if (t.reduce(add) === 10) {
                    result.push(t);
                }
                return;
            }
            values.forEach(iter(t));
        };
    }
    
    const
        add = (a, b) => a + b,
        values = [1, 2, 3, 4],
        result = [];

    values.forEach(iter([]));
    return result;
}

console.log(get4().map(a => a.join(' ')));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)

一种获取随机值的算法,没有所有可能组合的列表

它的工作原理是使用随机值和偏移量的因子,基于实际总和,指数,下一个索引所需的最小总和和最大总和.

偏移量通常是最小总和,或者总和与最大总和之差的较大值.为了获得该因子,将三个值用于乘以随机值的最小值.

该表根据给定值和获取所有值的迭代说明了总和和所需迭代的所有可能值.

在开始时,总和是小部分分配的值.其结果是与休息和第二块14...... 10,因为它是可能采取的值1... 5.第三轮遵循相同的规则.最后,将剩余的总和作为该值的偏移量.


一个带有1,......,5值和5元素的例子,它们具有15所有可能性的总和.

min:     1
max:     5
length:  5
sum:    15

smin = (length - index - 1) * min
smax = (length - index - 1) * max
offset = Math.max(sum - smax, min)
random = 1 + Math.min(sum - offset, max - offset, sum - smin - min)

    index     sum    sum min  sum max   random   offset
  -------  -------  -------  -------  -------  -------
_      0       15        4       20        5        1
       1       14        3       15        5        1
       1       13        3       15        5        1
       1       12        3       15        5        1
       1       11        3       15        5        1
_      1       10        3       15        5        1
       2       13        2       10        3        3
       2       12        2       10        4        2
       2       11        2       10        5        1
       2       10        2       10        5        1
       2        9        2       10        5        1
       2        8        2       10        5        1
       2        7        2       10        5        1
       2        6        2       10        4        1
_      2        5        2       10        3        1
       3       10        1        5        1        5
       3        9        1        5        2        4
       3        8        1        5        3        3
       3        7        1        5        4        2
       3        6        1        5        5        1
       3        5        1        5        4        1
       3        4        1        5        3        1
       3        3        1        5        2        1
_      3        2        1        5        1        1
       4        5        0        0        1        5
       4        4        0        0        1        4
       4        3        0        0        1        3
       4        2        0        0        1        2
       4        1        0        0        1        1
Run Code Online (Sandbox Code Playgroud)

代码示例采用想要的1,......,部分4长度4和总和10.

function getRandom(min, max, length, sum) {
    return Array.from(
        { length },
        (_, i) => {
            var smin = (length - i - 1) * min,
                smax = (length - i - 1) * max,
                offset = Math.max(sum - smax, min),
                random = 1 + Math.min(sum - offset, max - offset, sum - smin - min),
                value = Math.floor(Math.random() * random + offset);

            sum -= value;
            return value;
        }
    );
}

console.log(Array.from({ length: 10 }, _ => getRandom(1, 4, 4, 10).join(' ')));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)

  • 第二种算法产生某些分区的频率要比其他算法高得多(在本示例的情况下,是四倍)。 (2认同)
  • @Nina:根据分区算法的经验,我确定这是真的,但是我通过实验验证了这一点,以找到实际的偏差。我只运行了geRandom(1,4,4,10)一百万次,并在字典中计算了结果。 (2认同)
  • 结果“ 1 1 4 4”和“ 4 4 1 1”是最常见的(大约62,500)。大多数分区的数量约为15,000,但少数分区为21,000或31,000 (2认同)