Given Assumptions
An array of numbers is provided as input
Every call to makeRandom
will randomly select two numbers from the array and output their sum
Subsequent calls to makeRandom
should not reuse any number (id
) already used
list = [1,1,2,3,4,5];
// The number 1 can be used twice but only in different function calls
// The numbers 2,3,4,5 can only be used once
list = [1,1];
// This won't work since 1 == 1
Javascript Code
var list = [1,2,3,4,5,6,7,8,9]; // Initial list provided
var usable = list.slice(0); // Copy of initial list that will be altered by makeRandom
function makeRandom(){
// Checking feasibility...
let counts = {}; // Object to count unique numbers
for (var i = 0; i < usable.length; i++) {
counts[usable[i]] = 1 + (counts[usable[i]] || 0); // Fill counts with unique numbers from array
}
if(Object.keys(counts).length < 2){ // Ensure at least two unique numbers exist
console.log("List is too short!"); // Log an error if less than two unique numbers
return false; // Exit function if condition not met
}
// Generating random numbers and calculating 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 if first number isn't identical to the second one
}
usable.splice(id, 1); // Remove 2nd number from usable numbers
// console.log(a + " + " + b + " = " + (a+b)); // Optional log statement
return a+b; // Return sum of 1st and 2nd numbers
}
Note: To enhance understanding, the while loop is shown in full; it could be simplified using 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 previously in makeRandom
Example Scenario
var list = [1,2,3,4,5,6,7,8,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;
}
// Multiple function calls
makeRandom();
makeRandom();
makeRandom();
makeRandom();
makeRandom();
makeRandom();
// Altering the seed lists
var list = [1,1,1,1,1,9];
var usable = list.slice(0);
// Additional function calls
makeRandom();
makeRandom();
makeRandom();
Output Example
__Example 1__
list = [1,2,3,4,5,6,7,8,9]; // Sample 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,1,1,1,1,9]; // Sample list used
// console.log return
> makeRandom(); // 1 + 9 = 10 10
> makeRandom(); // List is too short! false
> makeRandom(); // List is too short! false
An Alternative Approach
Considering the changes made to your question...
It's unclear whether numbers can only be used once or if they cannot be used consecutively.
list = [1,2,3,4,5];
// Choose from // Chosen
> makeRandom(); // 1, 2, 3, 4, 5 // 1, 4
> makeRandom(); // 2, 3, 5 // 2, 3
> makeRandom(); // 1, 4, 5 // 1, 5
If that's the case, then the following alternative method may be more helpful
var list = [1,2,3,4,5,6,7,8,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,2,3,4];
// Make several calls to function
// With only 4 numbers, once the first pair is selected (e.g. 1 & 3), the pattern cycles between 1,3 -> 2,4 -> 1,3 -> 2,4
makeRandom();
makeRandom();
makeRandom();