根据条件替换2D数组的值

时间:2019-10-27 10:03:49

标签: javascript arrays

我得到了一个具有以下值的10 x 10数组:

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];

在此2D数组中,我必须随机选择六个值0(水平或垂直(也是随机的))并将其替换为值6。 我使用以下代码完成了此操作:

function tekenGrootstSchip(bord) {
    rand = Math.floor((Math.random() * 10));
    rand2 = Math.floor((Math.random() * 10));
    directie = Math.floor((Math.random() * 2));
    counter = 0;
    if (directie == 0) { 
    for(y = rand2; y < 10; y++) {
        if(counter < 6) {
            bord[rand][y] = 6;
            counter++;
    }
    }
    for(y = rand2; y > 0; y--) {
        if(counter < 6) {
            bord[rand][y] = 6;
            counter++;
    }
    }
    } else {
        for(x = rand; x < 10; x++) {
            if(counter < 6) {
                bord[x][rand2] = 6;
                counter++;
            }
        }
        for(x = rand; x > 0; x--) {
            if(counter < 6) {
                bord[x][rand2] = 6;
                counter++;
            }
        }
    }
}

对值6执行此操作后,我还必须对值4执行此操作。但是,值4的规则略有不同。您不能将4放在6上,也不能将4放在6旁边。而且值4仅占4位(所以4x1,而6是6x1)

因此,如果我的随机生成方向是水平的,则我的bord [x-1] [y],bord [x] [y]和bord [x + 1] [y],其中x和y初始化为随机值,其中y升至y + 1,y + 2,y + 3,y + 4(4x1)。所有这些值都必须对照== 0进行检查,如果为true,则可以初始化为零的零,否则不能初始化。如果是这样,我必须生成一个新的[x] [y]并再次检查这些条件,直到可以成功更改2D数组中的四个零为止。

尽管我对此有一个一般的想法,但我会遇到一个错误,例如,如果一个空值将被替换为四个,但是它旁边的一个不能被替换,因为它紧邻一个。 != 0值,我会被困在“非法”的四个数字上。

如果有人能以正确的方向帮助我,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

可行性

我们可以(简单地)证明,无论选择哪种6配置,我们都可以始终放置4

实际上,6的最大覆盖面积是9(3x3正方形)

000
060
000

(我们不能在4周围的边框中放置4)。

因此,最大6个配置覆盖区域的边界为6 * 9 = 54

000000xxxx
060060xxxx
000000xxxx
000000xxxx
060060xxxx
000000xxxx
000000xxxx
060060xxxx
000000xxxx
xxxxxxxxxx

我们可以在包含'x'的正方形中放置多达4个(远大于4个)

6代

我们假设董事会的指示如下:

0   1  2  3 ...  9
10 11 12  ...   19 
...
90...           99

将x移至底部,将y移至右侧

平方值id可以在(x,y)= ((id - id%10)/10, id%10)处找到 id:(x,y)->x*10+y

因此,我们只考虑0到99之间的数字(因为我们可以查找它们在网格中的关联位置(x,y))

我将使用从mdn毫不客气地从getRandomInt下面粘贴的副本

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}

最后我们可以画出0到99之间的数字。如果数字已经存在,则将其丢弃,否则将其获取

let indices = new Set
while(indices.size < 6){
    let idx = getRandomInt(0,99)
    if(!indices.has(idx)){
        indices.add(idx)
    }
}
return [...indices]

4代

  • 我们可以应用与以前相同的策略:在0到99之间绘制一个随机数,并在无效之前将其丢弃,直到找到4个有效位置为止

    1. 由于位置6而构建无效集
    let invalids = new Set
    indices.forEach(idx=>{
        let [x,y] = [(idx - idx%10)/10, idx%10]
        //add the adjacent squares
        for(let i = -1; i<=1; ++i){
            for(let j = -1; j<= 1; ++j){
                if( 0<=x+i<10  && 0 <= y+j < 10){//if the cell in the board....
                    invalids.add( (x+i)*10 + y+j )
                }
            }
        }
    })
  1. 从无效集中抽奖
    let out = []
    while(out.length < 4){
        let idx = getRandomInt(0,99)
        if(!invalids.has(idx)){
            invalids.add(idx)
            out.push(idx)
        }
    }
    return out

在最坏的情况下,这种方法可能没有那么有效:我们将有54%的概率得出无效数字!

因此,我们可以考虑仅包含有效数字的数组,并从中提取

let valids = Array(100).fill(0).reduce((oks, x,i)=>{
    if(invalids.has(i)) return oks
    return oks.push(i),oks
},[])

//take numbers from that array
let out = []
for(let i = 0; i<4; ++i){
    let idx = getRandomInt(0,valids.length)
    //notice that here we take the elem from valids
    //not just the idx from getRandomInt
    out.push(valids[idx])

    //and we takeout the element from valids
    valids.splice(idx, 1);
}
return out