自调整随机列表

Self adjusting random list

本文关键字:列表 随机 自调整      更新时间:2023-09-26

我有一个9列乘3行的网格(所以每列有3个槽)。必须在每列中至少标记一个插槽,并且标记的插槽不能超过3个。标记由1、2或3位数字表示。

总共必须有15个标记的插槽。为了实现这一点,我尝试了以下方法:

var valueLeft = 15;
while (valueLeft > 0)
{
    var ranValue = utils.getRandomInt(1,3);
    console.log('slots remaining: ' + (valueLeft - ranValue));
    if (ranValue >= valueLeft)
    {
            ranValue = valueLeft;
    }
    valueList.push(ranValue);
    valueLeft -= ranValue;
}
console.log(valueList);

但这通常会给我一个内部元素少于9的数字数组。我可以看出我的逻辑是有缺陷的,但我正在努力想办法让它总是给出一组9个元素,加起来总共15个。

例如,我最终可能会得到:[2,1,1,1,2,3,1,2,1]

例如,当我需要的是:[2,2,1,1,1,3,2,2]或[2,2,1,2,1,3,2,1]

等等

如有任何建议,不胜感激。请随意指责我逻辑感差:)

这个答案显示了与许多已经发布的方法类似的方法,但我觉得他们让它变得太复杂了。它可以非常简单:

function pad(list, size) {
    var total = list.length;
    while (total != size) {
        var i = utils.getRandomInt(0, 8);
        if (list[i] < 3) {
            list[i]++;
            total++;
        }
    }
    return list;
}
var valueList = pad(new Array(1,1,1,1,1,1,1,1,1), 15);

你不需要很多案例。正如许多其他人已经说过的那样,用1初始化数组。然后,只需在随机元素(其值还不是3)上加一,直到总数为15。

为什么不这样做:

从一个看起来像这样的数组开始:1,1,1,1,1,11,1,1,1

然后生成一个函数,该函数选取0到8之间的随机数6次。

如果同一个号码被提取了两次以上,跳过它并选择一个新的

然后将这6个数字与数组的索引相关联,并在每次拾取该数字时加1。

var i; var valueList = new Array(1,1,1,1,1,1,1,1,1);
for(i=0;i<6;i++)
{
var ranNum = utils.getRandomInt(0,8);
if(valueList[ranNum]<3) valueList[ranNum]+=1;
else i--;
}

只是测试了一下,改变了<6到<这对我很有用。祝你好运!

以下逻辑应该可以工作。您应该选择一个随机值(1-3内),这样选择不会导致我们无法为更多插槽选择随机值。

var gridLeft = 9
var valueLeft = 15
while(gridLeft>0) {
  var ranValue
  while(true) {
    ranValue = utils.getRandomInt(1,3);
    if (valueLeft-ranValue > 3*(gridLeft-1))
      continue;
    else if (valueLeft-ranValue < 1*(gridLeft-1))
      continue;
    else
      break;
  }
  valueList.push(ranValue);
  valueLeft -= ranValue;
  gridLeft -= 1
}