JavaScript: Random number in Loop - javascript

I was wondering how I can make a JavaScript loop that have to guess a correct number, 1-500.
Every loop there should be a new unique number that hasn't been guessed before. However it should guess in a random order.
Yes:
351, 201, 97 ...
No:
1, 2, 3, 4, 5, 5 ...
My code so far:
var number;
setInterval(function(){
number = Math.floor(Math.random() * 500) + 1;
console.log(number);
if (number == 350) {
console.log("Correct Number!")
}
}, 1000)

Here is my attempt at solving your problem using a fisher yates shuffle on an array with all numbers between 500.
var number = 121;
var numbArr = [];
for(var x = 1; x <= 500; x++){
numbArr.push(x);
}
function shuffle(array) {
var m = array.length, t, i;
// While there remain elements to shuffle…
while (m) {
// Pick a remaining element…
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}
shuffle(numbArr);
for(var x = 0; x < numbArr.length; x++){
if(number == numbArr[x]){
console.log("Found number at entry " + x);
}
}
The guessing with a random number comes by using the shuffle of all the possible numbers which means that it shall not be guessed again.

You will need to store the numbers you have already randomed.
If you encountered a number you have already randomed, random again.
var usedNumbers = [];
var interval = setInterval(function(){
var number = Math.floor(Math.random() * 500) + 1;
while(usedNumbers.includes(number)){
number = Math.floor(Math.random() * 500) + 1;
}
usedNumbers.push(number);
if (number == 350){
console.log("Correct Number!");
clearInterval(interval);
return;
}
console.log(number);
}, 500)

Related

random number that always makes a total of 100 into array

Hi i am trying to create an array that always has a total of 100 based on random numbers. I get it to work when there is 2 or 3 rows but i can't get it to work if there are more as 4. Meaning i need to change the middle section. Here is simple code i made: (the length is the number of rows in the array)
var array = []
var length = 3; //4 , 5 , 6 ...
var number;
var calculate;
var totalProcessed;
for (i = 0; i < length; i++) {
// FIRST ONE
if(i == 0){
number = Math.floor(Math.random() * 100) + 1;
console.log(number);
totalProcessed = number;
array.push(number)
}
// MIDDLE SECTION
if(i > 0 && i == length-1){
if(length > 2){
calculate = 100 - number;
number = Math.floor(Math.random() * calculate) + 1
totalProcessed = totalProcessed + number;
console.log(number);
array.push(number)
}
}
// LAST ONE
if(i == length -1){
var lastOne = 100-totalProcessed;
console.log(lastOne);
array.push(lastOne)
}
}
console.log(array);
How should i change the middle section to be able to capture the numbers?
There are two errors in this code:
First:
You should change the == to < in order to be able to loop more then 3 times:
if(i > 0 && i == length-1)
Second:
I think your error occurs on the following line. You subtract number from 100 which is the previous generated number. You should instead generate a random number from everything that is left:
calculate = 100 - number;
So I think you should subtract the totalProcessed value instead.
calculate = 100 - totalProcessed;
Full working snippet:
var array = []
var length = 5; //4 , 5 , 6 ...
var number;
var calculate;
var totalProcessed;
for (i = 0; i < length; i++) {
// FIRST ONE
if(i == 0){
number = Math.floor(Math.random() * 100) + 1;
console.log(number);
totalProcessed = number;
array.push(number)
}
// MIDDLE SECTION
if(i > 0 && i < length-1){
if(length > 2){
calculate = 100 - totalProcessed;
number = Math.floor(Math.random() * calculate) + 1
totalProcessed = totalProcessed + number;
console.log(number);
array.push(number)
}
}
// LAST ONE
if(i == length -1){
var lastOne = 100-totalProcessed;
console.log(lastOne);
array.push(lastOne)
}
}
console.log(array);
let total = 0;
array.forEach(el => total += el)
console.log(total)
You should replace the "==" in the if statement of the middle section by "<".
I found your approach a bit hard to comprehend. Is the question setup same as what code is trying to do? Therefore I wrote an alternate example that solves the question (as currently explained):
let limit = 100;
const numbers = [...Array(limit)].map(() => {
const random = Math.floor(Math.random() * 100) + 1;
if (limit - random > 0) {
limit -= random;
return random;
}
return null;
}).concat(limit).filter((num) => num)
console.log(numbers);
It goes through 100 iterations (in case there would come only 1's :D) and then decreases the limit. And if next random number fits into limit, it's added to the result, otherwise it's a null.
And if it happens that after 100 iterations there are still limit left, it's concatenated to an existing array. Finally we filter out all the "nulls" (numbers that didn't fit in to limit) and voila.

Fill an array with distanced random integers

I need an array to be filled with random integers
Those integers should be very distinct from each other i.e. must at least be 20 units of separation between each items
This is what i have tried so far :
var all = [];
var i = 0;
randomDiff();
function randomDiff() {
var num1 = randomNumber(10, 290); //chose a first random num in the range...
all[0] = num1; //...put it in first index of array
do // until you have 12 items...
{
var temp = randomNumber(10, 290); //...you pick a temporary num
var j;
for (j = 0; j < all.length; j++) // for each item already in the array
{
if ((temp < all[i] - 10) || (temp > all[i] + 10)) // if the temporary num is different enough from others members...
{
all.push(temp); //then you can store it
i++; //increment until....
console.log(all[i]);
}
}
}
while (i < 11) // ...it is filled with 12 items in array
}
////////////Radom in int range function///////////////////////////////////////
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
but always unsuccessful, including infinite loops...
Have a look on something like this:
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
const LIST_SIZE = 20;
const DISTANCE = 10;
const STOP_AFTER_ATTEMPT = 2000;
const randomList = [];
let attempt = 0;
while(randomList.length < LIST_SIZE && attempt < STOP_AFTER_ATTEMPT) {
const num = randomNumber(10, 290);
const numberExistsWithSmallerDistance = randomList.some(r => Math.abs(r - num) < DISTANCE)
if (!numberExistsWithSmallerDistance) {
randomList.push(num);
}
attempt++;
}
if (randomList.length === LIST_SIZE) {
console.log(randomList);
} else {
console.log("Failed to create array with distnct values after ", attempt, " tries");
}
Here's a solution that will always work, as long as you allow enough room in the range/separation/count you choose. And it's way more efficient than a while loop. It doesn't just keep trying until it gets it right, it actually does the math to make sure it's right the first time.
This comes at the cost of tending to lean towards certain numbers more than others (like from + (i * separation)), so take note of that.
function getSeparatedRadomInts(from, through, separation, count) {
if(through < from) return getSeparatedRadomInts(through, from, separation, count);
if(count == 0) return [];
if(separation == 0) return !!console.log("Please allow enough room in the range/separation/count you choose.");
//pick values from pool of numbers evenly stepped apart by units of separation... adding 1 to from and through if from is 0 so we can divide properly
var smallFrom = Math.ceil((from || 1) / separation);
var smallThrough = Math.floor((through + (from == 0)) / separation);
var picks = randoSequence(smallFrom, smallThrough).slice(-count).sort((a, b) => a - b);
if(picks.length < count) return !!console.log("Please allow enough room in the range/separation/count you choose.");
for (var i = 0; i < picks.length; i++) picks[i] *= separation;
//go through each pick and randomize with any wiggle room between the numbers above/below it... adding 1 to from and through if from is 0
for (var i = 0; i < picks.length; i++) {
var lowerBound = picks[i - 1] + separation || from || 1;
var upperBound = picks[i + 1] - separation || (through + (from == 0));
picks[i] = rando(lowerBound, upperBound);
}
//subtract 1 from all picks in cases where from is 0 to compensate for adding 1 earlier
for (var i = 0; i < picks.length; i++) if(from == 0) picks[i] = picks[i] - 1;
return picks;
}
console.log(getSeparatedRadomInts(10, 290, 20, 12));
<script src="https://randojs.com/1.0.0.js"></script>
To be clear, from is the minimum range value, through is the maximum range value, separation is the minimum each number must be apart from each other (a separation of 20 could result in [10, 30, 50, 70], for example), and count is how many values you want to pick.
I used randojs in this code to simplify the randomness and make it easier to read, so if you want to use this code, just remember to paste this in the head of your HTML document:
<script src="https://randojs.com/1.0.0.js"></script>

Rolling a die 60,000 times using if-else-if

I'm new to javascript and am facing trouble with the following problem.
Simulate rolling a die 60,000 times and display the frequency with which each face of the die finishes uppermost.
Use 6 variables to capture the frequencies and a 6-way if-else-if control structure need in the loop to increment them appropriately.
I know that I have to create an empty array which includes 6 variables and I have started the first iteration with 1.
What I don't understand is how to use the if-else-if statement to work through the 60000 iterations.
var array = [0, 0, 0, 0, 0, 0];
var i = 1;
You could introduce another variable for a random value between equal or greater than 0 and smaller than 6 and use it as index for the counting array.
Then you need a for loop, for counting the distribution of 60000 random values.
var array = [0, 0, 0, 0, 0, 0],
i,
r;
for (i = 0; i < 60000; i++) { // iterate 60000 times
r = Math.floor(Math.random() * 6); // generate random value
array[r]++; // increment counter
}
console.log(array);
for, Math.random:
var freqs = [0, 0, 0, 0, 0, 0];
var freqsLength = freqs.length; //* save array length into variable for more productivity
var rolls = 6000; //* how many time we want to roll dice
for(var i = 0; i < rolls; i++) { //* start rolling in loop
var j = Math.floor(Math.random() * freqsLength); //* get ramdom value
freqs[j]++; //* save freq result
}
alert(freqs);
Here's a working example with if-else:
var array = [0, 0, 0, 0, 0, 0];
var randomNumber;
for (var i = 0; i < 60000; i++) {
randomNumber = Math.floor(Math.random() * 6) + 1;
if(randomNumber === 1){
array[0]++;
}
else if(randomNumber === 2){
array[1]++;
}
else if(randomNumber === 3){
array[2]++;
}
else if(randomNumber === 4){
array[3]++;
}
else if(randomNumber === 5){
array[4]++;
}
else if(randomNumber === 6){
array[5]++;
}
}
console.log(array);
This question seems to be a homework, since you have to use if..else.
However, you don't need to use a if...else for this:
var arr = [0,0,0,0,0,0];
for(var i = 0; i < 60000; i++){
arr[~~(Math.random()*6)]++;
};
console.log(arr)
Explanation
The code has an for loop, which starts at 0 and ends at 60,000:
for(var i = 0; i < 60000; i++){
//...
};
For each iteration, a random value from 0 to 6 is generated...
Math.random()*6
... and converted to an integer using ~~.
Then, the element in the array at that random position is incremented:
arr[~~(Math.random()*6)]++;
Homework
Since this is in fact a homework and your requirements are:
Six variables
A six-way if..else
You can use this ugly, cumbersome and awkward code:
var one = two = three = four = five = six = 0;
for (var i = 0; i < 60000; i++) {
var random = ~~(Math.random() * 6) + 1;
if (random === 1) {
one++
} else if (random === 2) {
two++
} else if (random === 3) {
three++
} else if (random === 4) {
four++
} else if (random === 5) {
five++
} else if (random === 6) {
six++
}
};
var arr = [one, two, three, four, five, six];
console.log(arr)
Here's how I'd do it:
function randBetween(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
let counters = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0};
for (let i = 0; i < 60000; i++) {
counters[randBetween(1, 6)]++;
}
console.log(counters);
And here's what I'm guessing your teacher wants:
function randBetween(min, max) {
return Math.floor(Math.random() * max) + min;
}
let one = 0;
let two = 0;
let three = 0;
let four = 0;
let five = 0;
let six = 0;
for (let i = 0; i < 60000; i++) {
const n = randBetween(1, 6);
if (n === 1) { one++; }
else if (n === 2) { two++; }
else if (n === 3) { three++; }
else if (n === 4) { four++; }
else if (n === 5) { five++; }
else { six++; }
}
console.log(one, two, three, four, five, six);
You can decide for yourself which you think is the superior solution (Hint: How would you change each example to reflect rolling of a 100 sided die?)

frequency of random array integers

little stuck, please help! Trying to write code using the random number generator,initialize an array of size 50, with integer values in the
range 0..49 and compute the frequency of the numbers in the range 10..19. Here's what I have so far:
var array_nums = new Array (50);
var frequency = 0;
for (i=0; i<array_nums.length; i++){
array_nums [i] = Math.floor ((Math.random() * 50));
for (i=0; i<array_nums.length; i++){
if((i>=10) && (i<=19)){
frequency = frequency+ [i];
alert(frequency);
}
}
}
var array_nums = [];
var frequency = 0;
for (i=0; i < 50; i++) {
var randInt = Math.floor(Math.random()*50)
array_nums.push(randInt);
if(randInt >= 10 && randInt <= 19) {
frequency = frequency + 1;
}
}
document.getElementById('results').innerHTML = array_nums + '<br/><br/>frequency: ' + frequency;
<div id="results"></div>
We fill an array with 50 random numbers, then reduce it to an object that has the number of times each element between 10 and 19 occured, with a final "all" element that has the number of times all of the numbers between 10 and 19 occured.
var array_nums = Array.apply(null, Array(50)).map(function() {
return Math.floor(Math.random() * 50);
}).reduce(function (acc, curr) {
if (curr >= 10 && curr <= 19) {
acc[curr] = (acc[curr] || 0) + 1;
acc["all"]++;
}
return acc;
}, {all:0});
document.getElementById("results").innerHTML = JSON.stringify(array_nums);
<div id="results">

Generate random integer with ALL digits from 1-9

How do I generate a 9-digit integer that has all digits from 1-9? Like 123456798, 981234765, 342165978, etc.
Doing this:
var min = 100000000;
var max = 999999999;
var num = Math.floor(Math.random() * (max - min + 1)) + min;
does not work give me the integer that I want most of the time (does not have ALL digits from 1 to 9).
111111119 is not acceptable because each number must have at least one "1" in it, "2", "3", ... and a "9" in it.
Just start with the string 123456789 and shuffle it randomly as described in How do I shuffle the characters in a string in JavaScript?
String.prototype.shuffle = function () {
var a = this.split(""),
n = a.length;
for(var i = n - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a.join("");
}
This program, with little tweaks, will be a good addition to your custom utility belt.
Adapted from the _.shuffle function of Underscore.js library, which shuffles the list of data with Fisher-Yates Shuffle algorithm.
function getRandomNumber() {
var rand, index = 0, shuffled = [1, 2, 3, 4, 5, 6, 7, 8, 9];
shuffled.forEach(function(value) {
rand = Math.floor(Math.random() * ++index);
shuffled[index - 1] = shuffled[rand];
shuffled[rand] = value;
});
return shuffled.reduce(function(result, current) {
return result * 10 + current;
}, 0);
}
console.log(getRandomNumber());
This program will always return a number which has all the 9 numbers in it and the length is also 9.
Recurse!
var randomize = function (str) {
if (str.length == 9) return str;
var newDigit = Math.floor(Math.random()*9 + 1);
if (str.indexOf(newDigit) == -1) {
return randomize(str + newDigit);
} else {
return randomize(str);
}
}
There's a lot of room for optimisation there. Or just use a simple loop.
Working fiddle

Categories

Resources