来自数组项目的2个随机值

问题描述

Oive ive不得不制作一个程序来计算togheter 2的随机值。

在程序中应该有一个函数中的列表(1-9)。我应该从该列表中获取2个随机值(建议使用array.splice())。

选择了2个随机值后,程序应该将它们计算(相加)为总值randomvalue1 + randomvalue2 = totalvalue;

抓住! 执行两个随机值时,不能具有相同的值(5 + 5、3 + 3、2 + 2,依此类推,无效

第二场比赛! 随机不允许不允许连续执行两次。 我的意思是,程序不应允许randomvalue1连续两次(或多次)等于相同值(这也适用于randomvalue2)

到目前为止,我建议使用此代码,但它不会检查相同的值是否连续出现x次。

function makeRandom(list) {
 function getRandomIndex() {
     return Math.floor(Math.random() * list.length);
 }

let index1 = getRandomIndex(),index2 = getRandomIndex();

while (index1 === index2) index2 = getRandomIndex();

return list[index1] + '+' + list[index2];
}
console.log(makeRandom([1,2,3,4,5,6,7,8,9]));

解决方法

您可以进行索引并循环,直到获得用于从数组获取值的其他索引为止。

function makeRandom(list) {
    function getRandomIndex() {
        return Math.floor(Math.random() * list.length);
    }
    
    let index1 = getRandomIndex(),index2 = getRandomIndex();

    while (index1 === index2) index2 = getRandomIndex();

    return list[index1] + '+' + list[index2];
}

console.log(makeRandom([1,2,3,4,5,6,7,8,9]));

排除某些索引的方法

function makeRandom(list,exclude = []) {
    function getRandomIndex() {
        return Math.floor(Math.random() * list.length);
    }
    function getFreeIndex() {
        let index;

        if (exclude.length >= list.length) return;

        do index = getRandomIndex();
        while (exclude.includes(index))

        exclude.push(index);
        return index;
    }
    
    return getFreeIndex() + '+' + getFreeIndex();
}

console.log(makeRandom([1,9],[2,3]));

,

更新的答案

对问题的编辑明确了一些其他要求,这意味着原始解决方案(如下)不能满足要求。这个版本似乎很有用。

我们引入了一个从固定数组中随机选择的函数,但绝不会选择任何n-最近使用过的项目。因此,如果我们使用n的{​​{1}}和4的{​​{1}}来调用此函数,我们将返回一个函数,该函数将随机选择一个值,并在下次调用时会随机选择另一个,在第三个呼叫时会再选择一个,然后再呼叫第四个。这四个之间不会有重复。第五个可能与第一个相同,或者可以是不在该列表中的任何其他值。第六次调用可能与第二次调用相同(或者,如果第五次调用未被重用,则与第一轮调用的值相同),依此类推。

arr

我们会跟踪两个列表:最近未使用的列表和我们现在无法重用的列表([1,9]const noRepeatRandom = (n,arr) => { // TODO: error if n >= arr.length let available = [...arr] let used = [] return () => { const nextIdx = Math .floor (Math .random() * available .length) const next = available [nextIdx] used .push (next) available .splice (nextIdx,1) if (used .length >= n) { available .push (used .shift()) } return next } } const myRandom = noRepeatRandom (4,[1,9]) // display the results of a bunch of calls to `myRandom()` console .log (...Array.from({length: 30},myRandom))。)最初,我们只填写available,但是一旦到达used,我们便开始从used列表中删除最早的元素,并将其添加到n中。

请注意,应该对used和数组的长度进行错误检查。如果available,这应该会失败。我将其保留为练习。另外请注意,如果使用n,则将重复执行相同的n >= arr.length项目,因为每次都只有一个选项可供选择。


原始答案

此版本不符合明确的要求。它仍然是一种有用的技术,但不能解决问题。

我将对数组进行部分改组。以下代码是Fisher-Yates shuffle的递归版本,已修改为在选择n == arr.length - 1元素后停止。它不会修改您的输入数组。

然后,通过将arr.length部分应用到我们的(咖喱函数)来构建n

pickTwo
2

,

假设

  1. 您有一个数字数组作为输入

  2. 每次调用makeRandom时,应从数组中随机选择两个数字并输出总和

  3. 以后每次对makeRandom的呼叫应使用已使用的任何数字(id

     list = [1,1,5];
     // The number 1 could be used twice (but only in different calls to makeRandom)
     // The numbers 2,5 can only be used once
    
     list = [1,1];
     // Shouldn't work because 1 == 1
    

JS代码

var list    = [1,9];    // Your seed list
var usable  = list.slice(0);          // Copy of your seed list {which we will alter with makeRandom}
function makeRandom(){
    // Check it's possible...
    let counts = {};                                       // Create object to count unique numbers
    for (var i = 0; i < usable.length; i++) {
        counts[usable[i]] = 1 + (counts[usable[i]] || 0);  // Iterate array and fill counts
    }
    if(Object.keys(counts).length < 2){                    // Check there are at least two unique numbers
        console.log("List is too short!");                 // Log error if <2
        return false;                                      // Exit function if <2
    }


    // Get random numbers and output sum...
    let id = Math.floor(Math.random() * usable.length)   // Randomly select an id from usable numbers
    let a  = usable[id];                                 // Set first number
    usable.splice(id,1);                                // Remove 1st number from usable numbers
    
    let b;
    while(true){                                         // Loop until numbers are different
        id = Math.floor(Math.random() * usable.length);  // Randomly select an id from usable numbers
        b  = usable[id];                                 // Set second number
        if(a !== b)break;                                // Check 1st number isn't the same as the second number
    }
    usable.splice(id,1);                                // Remove 2nd number from usable numbers
//  console.log(a + " + " + b + " = " + (a+b));          // Log for debugging if required
    return a+b;                                          // Return sum of 1st and 2nd numbers
}

注意:为了便于理解,我已经完全键入了while循环;可以使用 do...while(...)将其缩短:

    let b;
    do b = list[Math.floor(Math.random() * list.length)];  // Set second number
    while(a==b)                                            // Re-set second number if a == b OR if b was used in the last call to makeRandom

示例

var list    = [1,9];
var usable  = list.slice(0);
function makeRandom(){
    let counts = {};
    for (var i = 0; i < usable.length; i++) {
        counts[usable[i]] = 1 + (counts[usable[i]] || 0);
    }
    if(Object.keys(counts).length < 2){
        console.log("List is too short!");
        return false;
    }
    let id = Math.floor(Math.random() * usable.length)
    let a  = usable[id];
    usable.splice(id,1);
    let b;
    while(true){
        id = Math.floor(Math.random() * usable.length);
        b  = usable[id];
        if(a !== b)break;
    }
    usable.splice(id,1);
    console.log(a + " + " + b + " = " + (a+b));
    return a+b;
}
// Make several calls to function
makeRandom();
makeRandom();
makeRandom();
makeRandom();
makeRandom();
makeRandom();

// Change the seed lists
var list    = [1,9];
var usable  = list.slice(0);

// Make several calls to function
makeRandom();
makeRandom();
makeRandom();

示例输出

__Example 1__
list = [1,9]; // Example list used

                // console.log           return
> makeRandom(); // 4 + 2 = 6             6
> makeRandom(); // 1 + 8 = 9             9
> makeRandom(); // 9 + 3 = 12            12
> makeRandom(); // 6 + 7 = 13            13
> makeRandom(); // List is too short!    false
> makeRandom(); // List is too short!    false

__Example 2__
list = [1,9]; // Example list used

                // console.log           return
> makeRandom(); // 1 + 9 = 10            10
> makeRandom(); // List is too short!    false
> makeRandom(); // List is too short!    false

替代

查看了您的问题的更新...

我不清楚数字是否只能使用一次(如果不能直接使用)。

list = [1,5];
                 // Choose from      // Chosen
> makeRandom();  // 1,5    // 1,4
> makeRandom();  // 2,5          // 2,3
> makeRandom();  // 1,5          // 1,5

如果是这种情况,那么以下内容可能会更有用

var list = [1,9];    // Your seed list
var used = [];           // Last used pair of numbers
function makeRandom(){
    // Check it's possible...
    let counts = {};                                       // Create object to count unique numbers
    for (var i = 0; i < list.length; i++) {
        counts[list[i]] = 1 + (counts[list[i]] || 0);  // Iterate array and fill counts
    }
    if(Object.keys(counts).length < 4){                    // Check there are at least four unique numbers: any less and we'll end up in an infinite loop on the second call of makeRandom
        console.log("List is too short!");                 // Log error if <2
        return false;                                      // Exit function if <2
    }


    // Get random numbers and output sum...
    let a;
    do a = list[Math.floor(Math.random() * list.length)];  // Set first number
    while(used.includes(a))                                // Reset first number if a was used in the last call to makeRandom
    let b;
    do b = list[Math.floor(Math.random() * list.length)];  // Set second number
    while(a==b || used.includes(b))                        // Re-set second number if a == b OR if b was used in the last call to makeRandom

    used = [a,b];                                         // Set last used numbers
    console.log(a + " + " + b + " = " + (a+b));            // Log for debugging if required
    return a+b;                                            // Return sum of 1st and 2nd numbers
}

// Make several calls to function
makeRandom();
makeRandom();
makeRandom();
makeRandom();
makeRandom();
makeRandom();

// Change the seed lists
var list    = [1,4];

// Make several calls to function
// Notice with only 4 numbers once the first pair is selected (e.g. 1 & 3) the pattern cycles 1,3 -> 2,4 -> 1,4
makeRandom();
makeRandom();
makeRandom();