问题描述
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
,
假设
-
您有一个数字数组作为输入
-
每次调用
makeRandom
时,应从数组中随机选择两个数字并输出总和 -
以后每次对
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();