while loop. can't hardcode the while statement - javascript

function start() {
var output = "";
var index = 0;
var total = 0;
var average = 0;
var arr = []
while(arr.length < 12){
var randomnumber = Math.ceil(Math.random()*20)
if(arr.indexOf(randomnumber) > -1) continue;
arr[arr.length] = randomnumber;
}
output = output + "List of all values in the array: " + arr;
output = output + "<br/>" + "Total number of values in the array: " + arr.length + "<br/>";
while(index < arr.length) {
total = total + arr[index];
index++;
}
average = total / index;
output = output + "Total of all values: " + total + "<br/>";
output = output + "Average of all values: " + average;
document.getElementById("msg").innerHTML = output;
}
I was told I am not allowed to hardcode the statement, how to I go about changing the 'while' statement so I am not hardcoding?

Probably they mean
var arr = new Array(12);
var randIndex=0;
while(randIndex < arr.length){
var randomnumber = Math.ceil(Math.random()*20)
if(arr.indexOf(randomnumber) > -1) continue;
arr[randIndex] = randomnumber;
randIndex++;
}

Looks like a school assignment. If you are not supposed to hardcode the number of elements in array (currently 12) then you will need to get that number from user in some way. Or alternatively use a random number as shown below.
Note: there is a catch if you let the user specify the number of elements. I'll keep it for you to explore and fix.
function start(len) {
var output = "";
var index = 0;
var total = 0;
var average = 0;
var arr = []
while(arr.length < len){
var randomnumber = Math.ceil(Math.random()*20)
if(arr.indexOf(randomnumber) > -1) continue;
arr[arr.length] = randomnumber;
}
output = output + "List of all values in the array: " + arr;
output = output + "<br/>" + "Total number of values in the array: " + arr.length + "<br/>";
while(index < arr.length) {
total = total + arr[index];
index++;
}
average = total / index;
output = output + "Total of all values: " + total + "<br/>";
output = output + "Average of all values: " + average;
document.getElementById("msg").innerHTML = output;
}
// start(10); // you can get the number of elements in array from user and pass it here. I'm passing hardcoded 10 for now.
start(Math.ceil(Math.random()*20)); // alternatively passing a random number
<div id='msg'>
</div>

Related

How to generate unique random numbers

I’m trying to generate 5 unique random numbers between two numbers. The sixth number is a random number between another set of numbers but it doesn’t have to be unique. I tried to ensure the uniqueness of each number by placing the first randomly generated number in an array.
Then each subsequent randomly generated number is checked against the numbers in this array. Any generated number matching a number in the array will be discarded and a new one is generated until one that doesn’t match any in the array is is found. My code doesn’t work because occasionally it produces duplicates.
How is this fixed?
https://jsfiddle.net/L3h0rf5q/
var btnGen = document.getElementById('generate');
var fiveNum = document.getElementById('fiveNums');
var lastNum = document.getElementById('lastNum');
btnGen.addEventListener('click', function () {
let ranNum;
let firstFive = "";
let pb = "";
let oldNum;
ranNum = GenerateNumbers();
ranNum.sort(
(a, b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
);
for(let i=0; i<ranNum.length; i++){
if(i<ranNum.length - 1){
if(ranNum[i].toString().length<2){
firstFive += "0" + ranNum[i].toString() + " " + " " + " " + " " + " " + " "
}else{
firstFive += ranNum[i].toString() + " " + " " + " " + " " + " " + " "
}
}else{
if(ranNum[i].toString().length<2){
pb = "0" + ranNum[i].toString();
}else {
pb = ranNum[i].toString();
}
}
fiveNum.innerHTML = firstFive;
lastNum.innerHTML = pb;
}
});
function GenerateNumbers() {
let randomNums = [];
let selectedNums = [];
let newNum = undefined;
for (let i = 0; i < 6; i++) {
if (i == 0) {
newNum = Math.floor(Math.random() * 75) + 1
randomNums[i] = newNum;
selectedNums.push(newNum);
}
if (i >0 && i < 5){
while (selectedNums.includes(newNum)) {
newNum = Math.floor(Math.random() * 75) + 1
}
randomNums[i] = newNum;
//add to an array
selectedNums.push(newNum);
}
if (i == 5) {
randomNums[i] = Math.floor(Math.random() * 42) + 1
}
}
return randomNums;
}
<div style="margin-left:20%; width:500px; font-weight:bold; font-size:30px;">
<button id="generate" style="margin-left:36%">Generate Numbers</button>
<br><br>
<div>
<label style="margin-left:20%">Generate Numbers</label>
<br>
<div style="background-color:black">
<span id="fiveNums" style="margin-left: 10%; width:80%; color:blue;"></span>
<span id="lastNum" style="color:blue;"></span>
</div>
</div>
the approach is to make an array with all possible values, shuffle it, and then grab 5 of them (and for that extra value you want, just calculate it separately). you can do this with plain javascript if you want:
function shuffle(arr) {
let i = arr.length;
while(i != 0) {
let j = Math.floor(Math.random() * i--);
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
//fill arr with all possible values
var arr = [];
for(var i = 50; i <= 100; i++) arr.push(i);
//shuffle
shuffle(arr);
//grab 5
console.log(arr.slice(-5));
//and the extra one
console.log(Math.floor(Math.random() * 76) + 75);
But doing it with rando.js is a lot nicer:
console.log(randoSequence(50, 100).slice(-5));//first five
console.log(rando(75, 150));//the other one
<script src="https://randojs.com/2.0.0.js"></script>

JavaScript arr.indexOf() always gives -1

I have a random number generator and a pick of one of the numbers inside. I'm trying to get the position of the number, So I used index.of() but it always shows '-1'.
I thought this would be the most direct way of finding the location of a particular number within an array. Am I wrong?
const shuffle = arr => {
let a = arr.slice(0); // take a copy
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
};
var arr = [];
var UserNumber = 10;
var BallNumber = 4;
var RandomNumber = Math.floor(Math.random() * UserNumber) + 1;
while (arr.length < BallNumber) {
var r = Math.floor(Math.random() * UserNumber) + 1;
if (arr.indexOf(r) === -1) {
arr.push(r);
}
console.log(r);
}
var selected = shuffle(arr).slice(0, 1);
document.write("<p> The random Number to choose is " + selected + "</p>");
document.write("<p> The Random Numbers are " + arr + "</p>");
document.write("<p> The position is " + arr.indexOf(selected) + "</p>");
Array.prototype.slice returns an array:
var selected = shuffle(arr).slice(0, 1)
Here, selected is now an array with a single element. But objects are never === to anything besides themselves, and since indexOf uses === to determine indicies, it'll always return -1.
Extract the first value from the shuffled array instead:
var selected = shuffle(arr)[0]
const shuffle = arr => {
let a = arr.slice(0); // take a copy
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
};
var arr = [];
var UserNumber = 10;
var BallNumber = 4;
var RandomNumber = Math.floor(Math.random() * UserNumber) + 1;
while (arr.length < BallNumber) {
var r = Math.floor(Math.random() * UserNumber) + 1;
if (arr.indexOf(r) === -1) {
arr.push(r);
}
}
var selected = shuffle(arr).slice(0, 1)[0];
document.write("<p> The random Number to choose is " + selected + "</p>");
document.write("<p> The Random Numbers are " + arr + "</p>");
document.write("<p> The position is " + arr.indexOf(selected) + "</p>");
slice returns an array, so you'll have to grab the first element, something like:
const shuffle = (arr) => {
let a = arr.slice(0); // take a copy
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
};
var arr = [];
var UserNumber = 10;
var BallNumber = 4;
var RandomNumber = Math.floor(Math.random() * UserNumber) + 1;
while (arr.length < BallNumber) {
var r = Math.floor(Math.random() * UserNumber) + 1;
if (arr.indexOf(r) === -1) {
arr.push(r);
}
console.log(r);
}
var selected = shuffle(arr).slice(0, 1);
document.write("<p> The random Number to choose is " + selected + "</p>");
document.write("<p> The Random Numbers are " + arr + "</p>");
document.write("<p> The position is " + arr.indexOf(selected[0]) + "</p>");

How to display average from list using javascript?

I just want to show their average from the list when the user stored a value in the list
But I try to use document.write(); but it's doesn't work for me
I want to show the average below the list
function listtable()
{
var score;
var scoreArray = [];
var scoreOutput;
var slenght;
var sum = 0;
do
{
score = prompt("Please enter score and Enter -1 to stop
entering");
score = parseInt(score);
if (score >=0 )
{
scoreArray[scoreArray.length] = score;
}
} while (score != -1);
scoreOutput = "<ul>";
for (i = 0; i < scoreArray.length; i++)
{
scoreOutput += "<li>" + scoreArray[i] + "</li>";
}
scoreOutput += "</ul>";
for (i = 0; i < scoreArray.Length; i++)
{
sum += parseInt(score[i]);
}
var avarage = sum/scoreArray.length;
document.getElementById("display").innerHTML = scoreOutput;
document.write("The Avarage Score is: " + average);
}
You have a couple of typos in your code:
parseInt(score[i]) should be parseInt(scoreArray[i])
i < scoreArray.Length should be scoreArray.length with a lowercase l
The variable should be average not avarage
function listtable() {
var score;
var scoreArray = [];
var scoreOutput;
var slenght;
var sum = 0;
do {
score = prompt("Please enter score and Enter -1 to stop entering ");
score = parseInt(score);
if (score >= 0) {
scoreArray[scoreArray.length] = score;
}
}
while (score != -1);
scoreOutput = "<ul>";
for (i = 0; i < scoreArray.length; i++) {
scoreOutput += "<li>" + scoreArray[i] + "</li>";
}
scoreOutput += "</ul>";
for (i = 0; i < scoreArray.length; i++) {
sum += parseInt(scoreArray[i]);
}
var average = sum / scoreArray.length;
document.getElementById("display").innerHTML = scoreOutput;
document.write("The Avarage Score is: " + average);
}
listtable()
<span id="display" />
(Please search how to debug javascript code using degbugger; and dev tools. You can avoid trivial errors)
Try this:
function listtable() {
var score;
var scoreArray = [];
var scoreOutput;
var slenght;
var sum = 0;
var i;
do {
score = prompt("Please enter score and Enter -1 to stop entering");
score = parseInt(score);
if (score >=0 ) {
scoreArray[scoreArray.length] = score;
}
} while (score != -1);
scoreOutput = "<ul>";
for (i = 0; i < scoreArray.length; i++) {
console.log(scoreArray[i])
sum += parseInt(scoreArray[i]);
scoreOutput += "<li>" + scoreArray[i] + "</li>";
}
scoreOutput += "</ul>";
var average = sum / scoreArray.length;
document.getElementById("display").innerHTML = scoreOutput;
document.write("The Average Score is: " + average);
}
listtable();
<div id="display"></div>
I have made the following changes in your code:
You have used 2 for loop which is not needed, I have added the code in the single for loop. (Optimized, Not an issue)
The variable name is defined as average but you used avarage in the document.write.
You didn't define the var i in your code and directly initializing it in the loop.
There are multiple issue in your code,
You need to store elements in an array with incremental counter instead of storing it in an array length i.e Intested of scoreArray[scoreArray.length] = score; you need to store value at particular index.
Like.
var index = 0;
do
{
score = prompt("Please enter score and Enter -1 to stop
entering");
score = parseInt(score);
if (score >=0 )
{
scoreArray[index++] = score;
//Use index with incremental operator
}
} while (score != -1);
While calculating sum you need to read value from scoreArray not from score. In your code scoreArray is an array not score variable.
correct code,
for (i = 0; i < scoreArray.Length; i++)
{
sum += parseInt(scoreArray[i]);
//Use scoreArray instead of score
}
Now calculate average and print in HTML DOM
Like,
document.write("The Avarage Score is: " + avg);
Here is sample piece of code to print average.
//Declaration of variables
var scoreArray = [1, 2, 3, 4, 5];
var i, index = 0, sum = 0;
//Calculate sum
for(i = 0; i < scoreArray.length; i++)
sum += scoreArray[i];
//Calculate average
var avg = sum/scoreArray.length;
document.write("The Avarage Score is: " + avg);

Unbalanced tree from document.write and variable un-defined

I am writing a program to display total test grades and avg with a loop. however when I try to test it, I cant get the final message "Good Job" to show up and I am getting a error for unbalanced tree and undefined "Avg" variable. I dont see how "avg" is undefined when it works during the loop just not after
var Testscore = 0;
var Testcount = 0;
var Total = 0;
var Avg = 0;
do {
Testscore = prompt("Enter the test score ", 0);
Testcount = (Testcount + 1);
Total = parseFloat(Testscore) + parseFloat(Total);
Avg = (Total / Testcount);
document.write("Total test score is " + Total + "<br>");
document.write("Average test score is " + Avg + "<br>" + "<br>");
} while (Testcount < 4)
Avg = (Total / Testcount);
if (avg > 80) {
document.write("Good Job!");
} else {
documet.write("Try harder..");
}
You just had a few typos in your code!
avg and Avg are different, as variables are case sensitive.
Additionally, there's a documet instead of document
var Testscore = 0;
var Testcount = 0;
var Total = 0;
var Avg = 0;
do
{
Testscore = prompt("Enter the test score ",0);
Testcount = (Testcount + 1);
Total = parseFloat(Testscore) + parseFloat(Total);
Avg = (Total / Testcount);
document.write("Total test score is " + Total + "<br>");
document.write("Average test score is " + Avg + "<br>" + "<br>");
} while (Testcount < 4)
Avg = (Total / Testcount);
if (Avg > 80)
{
console.log("Good Job!");
}
else
{
console.log("Try harder..");
}

How can I numerically sort an array in Javascript when the number is the first part of each entry?

I am creating a list of words from a String. I then split that string into individual words, gather a count of how many times each word is repeated, and display it. Everything there works perfectly. However, the result displays the words and counts in no specific order. I will want to display them with the highest number first. I have generated the following code:
<!DOCTYPE html>
<html>
<body>
<p>Click the button to display the array values after the split.</p>
<button onclick="analyze()">Analyze</button>
<p id="displayText"></p>
<script>
function analyze() {
var str = "This this is is is is is is is is is is is is is is is just just a test test test";
var res = str.split(" ");
document.getElementById("displayText").innerHTML = res;
document.getElementById("displayText").innerHTML += "<br/><br/>The amount of words is: " + res.length + "<br/><br/><br/>";
document.getElementById("displayText").innerHTML += "The list of words:<br/><br/>";
var words = [];
var wordsWithCount = [];
for (i = 0; i < res.length; i++) {
words.push(res[i]);
document.getElementById("displayText").innerHTML += words[i] + "<br/><br/>";
}
var current = null;
var cnt = 0;
for (var i = 0; i < words.length; i++) {
if (words[i] != current) {
if (cnt > 0) {
document.getElementById("displayText").innerHTML += "<br/><br/>" + cnt + " - " + current + "<br/>";
wordsWithCount.push(cnt + " - " + current);
}
current = words[i];
cnt = 1;
} else {
cnt++;
}
}
if (cnt > 0) {
document.getElementById("displayText").innerHTML += "<br/><br/>" + cnt + " - " + current + "<br/>";
wordsWithCount.push(cnt + " - " + current);
}
wordsWithCount.sort();
document.getElementById("displayText").innerHTML += "<br/><br/><br/><br/><br/>The list of SORTED words:<br/><br/>";
for (i = 0; i < wordsWithCount.length; i++) {
document.getElementById("displayText").innerHTML += wordsWithCount[i] + "<br/><br/>";
}
}
</script>
</body>
</html>
This is the last bit of the output. As you can see, it's being sorted, but only by first digit. Thus, 15 is displayed before 2. Any thoughts?
The list of SORTED words:
1 - This
1 - a
1 - this
15 - is
2 - just
3 - test
I will most likely need to break this into two arrays at some point, because I will want the user to be able to copy and paste all of the words, without the numbers. However, I assume that will need to be the last step, because if I break the frequency of each word into it's own array of numbers, and keep the words in their own array, then the sort function will sort one array, and the other array will not follow.
Using a parseInt() method and the solution found here (How to sort an array of integers correctly) to the mix it works!
replace wordsWithCount.sort(); with:
function sortNumber(a,b) {
return parseInt(a) - parseInt(b);
}
wordsWithCount.sort(sortNumber);
Live here: https://www.w3schools.com/code/tryit.asp?filename=FFGXRIN0VZWO
Do it using Intl.Collator. Like this:
var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
var test = ['1 - this', '3 - this', '14 - this'];
test.sort(collator.compare);
Outputs ["1 - this", "3 - this", "14 - this"]
var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
var test = ['1 - this', '3 - this', '14 - this'];
console.log(test.sort(collator.compare));
You can just add a custom compare function to pass into your wordsWithCount.sort() call. Here I declared a function called compareWordCount and used the sugfested method by #Pointy; using parseInt to ignore all non integer parts appended to array value. Take a look at this working snippet:
<!DOCTYPE html>
<html>
<body>
<p>Click the button to display the array values after the split.</p>
<button onclick="analyze()">Analyze</button>
<p id="displayText"></p>
<script>
function compareWordCount(a,b) {
if (parseInt(a) < parseInt(b))
return -1;
return 1;
}
function analyze() {
var str = "This this is is is is is is is is is is is is is is is just just a test test test";
var res = str.split(" ");
document.getElementById("displayText").innerHTML = res;
document.getElementById("displayText").innerHTML += "<br/><br/>The amount of words is: " + res.length + "<br/><br/><br/>";
document.getElementById("displayText").innerHTML += "The list of words:<br/><br/>";
var words = [];
var wordsWithCount = [];
for (i = 0; i < res.length; i++) {
words.push(res[i]);
document.getElementById("displayText").innerHTML += words[i] + "<br/><br/>";
}
var current = null;
var cnt = 0;
for (var i = 0; i < words.length; i++) {
if (words[i] != current) {
if (cnt > 0) {
document.getElementById("displayText").innerHTML += "<br/><br/>" + cnt + " - " + current + "<br/>";
wordsWithCount.push(cnt + " - " + current);
}
current = words[i];
cnt = 1;
} else {
cnt++;
}
}
if (cnt > 0) {
document.getElementById("displayText").innerHTML += "<br/><br/>" + cnt + " - " + current + "<br/>";
wordsWithCount.push(cnt + " - " + current);
}
wordsWithCount.sort(compareWordCount);
document.getElementById("displayText").innerHTML += "<br/><br/><br/><br/><br/>The list of SORTED words:<br/><br/>";
for (i = 0; i < wordsWithCount.length; i++) {
document.getElementById("displayText").innerHTML += wordsWithCount[i] + "<br/><br/>";
}
}
</script>
</body>
</html>

Categories

Resources