Generate random answers for each button in Javascript / JQuery - javascript

I have been pouring over answers on stack overflow for my problem. All of them have resulted in infinite loops which have caused my code to crash several times. Let me start by saying I am a beginner. I'd also like to iterate that for my current project I have to use Javascript/JQuery as requested.
I am creating a math quiz game that generates random equations. Along with the random equations I would like to generate random answers. I have the random equations and answers generated, but for some reason I can't get my quiz app to generate unique random answers without crashing. I have tried populating the array first, then sorting the array, and splicing out duplicates and reiterating through the array. I have also tried to check for duplicates before the random number is populated in the array. None seem to work. I know there are similar questions to mine, and they work when NOT incorporated in my code. I think I'm going about it the wrong way, in which case I'd love for a second pair of eyes. Thanks!
let a, b, op, correctAnswer, ansb;
const novice = () => {
const num = () => ~~(Math.random() * 10) + 1
a = num()
b = num()
op = ["*", "+", "/", "-"][Math.floor(Math.random() * 4)];
$("#question").text(`${a} ${op} ${b}`).show()
correctAnswer = (() => {
switch (op) {
case "*": return a * b
case "+": return a + b
case "/": return a / b
case "-": return a - b
}
})()
if (!Number.isInteger(correctAnswer)) {
novice()
// equations.pop()
}
let randomAnswers = [correctAnswer]
for (let x = 0; randomAnswers.length < 4; x++) {
// ! i need to sort the array after its already pushed in there??
let rand = Math.floor(Math.random() * correctAnswer + 20)
// randomAnswers.push(rand)
// console.log(randomAnswers.indexOf(x), randomAnswers.lastIndexOf(x))
// if (randomAnswers.indexOf(rand) !== randomAnswers.indexOf(x)) {
randomAnswers.push(rand)
// }
}
let randAnsw = randomAnswers.sort(() => Math.random() - 0.5)
$("#a0").text(randAnsw[0]).attr("value", `${randAnsw[0]}`)
$("#a1").text(randAnsw[1]).attr("value", `${randAnsw[1]}`)
$("#a2").text(randAnsw[2]).attr("value", `${randAnsw[2]}`)
$("#a3").text(randAnsw[3]).attr("value", `${randAnsw[3]}`)
}
// const nextNov = () => {
// novice()
// selectNovAnswer()
// }
// const selectNovAnswer = () => {
// $('#answer-buttons .btn').each(function () {
// $(this).unbind("click").on("click", function () {
// if ($(this).attr("value") == correctAnswer) {
// NextNov()
// } else {
// // startOver()
// // $(".answ").attr("disabled", 'disabled')
// $("#question").append(`<span class="text-danger"> = ${correctAnswer}</span>`)
// }
// })
// })
// }
$("#start").on("click", function () {
novice()
// selectNovAnswer()
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fast Math Example</title>
<link rel="stylesheet" href="bootstrap-4.5.3-dist/css/bootstrap.min.css">
</head>
<body>
<button id="start" type="button">Start</button>
<h1 id="question"></h1>
<div id="answer-buttons">
<button id="a0" class="btn" type="button"></button>
<button id="a1" class="btn" type="button"></button>
<button id="a2" class="btn" type="button"></button>
<button id="a3" class="btn" type="button"></button>
</div>
<script src="jquery-3.6.0.min.js"></script>
<script src="bootstrap-4.5.3-dist/js/bootstrap.min.js"></script>
<script src="index.js"></script>
</body>
</html>

Try generating randoms in b/w ranges of number so that you always get unique numbers
const randomBtwRange = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
//[num - 10, num, num + 10, num + 20 ]
const generate3Randoms = (num) => {
return [
randomBtwRange(num - 10, num - 1),
randomBtwRange(num + 1, num + 10),
randomBtwRange(num + 11, num + 20)
]
}
const answer = 12
console.log(
[answer, ...generate3Randoms(answer)]
.sort(_ => Math.random() - 0.5)
)

Related

Run for loop sequence and stop random not only the last element

Hi i am new to jquery/javascript , i have a for loop where at, i need to run it in sequence from 1 to 4. but when the "for loop" stop, the element should stop either 1,2,3 or 4 (randomly). is it possible? cause now what i did is , it always stop in count 4. kindly help. Thank you..
You can access the code here:
https://codesandbox.io/s/angry-hodgkin-esr8f?file=/index.html:0-904
This is the code:
<!DOCTYPE html>
<html>
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
type="text/javascript"
></script>
</head>
<body style="background: gray;">
<button id="k">Hello</button>
</body>
</html>
<script>
var data = [
{
count: "1",
name: "one"
},
{
count: "2",
name: "two"
},
{
count: "3",
name: "three"
},
{
count: "4",
name: "four"
}
];
$("#k").click(function () {
let count = 0;
const interVal = setInterval(function () {
for (let i = 0; i < data.length; i++) {
// loop through the data array
const _data = data[i];
setTimeout(function () {
console.log("data", _data.count);
}, 50 * i);
}
count += 1;
if (count === 3) clearInterval(interVal);
}, 600);
});
</script>
I think the easiest answer would be to generate a random number between the range you are interested in, and use that number to be the end of the for loop. You can use the following function:
function getRndInteger(min, max) {
return Math.floor(Math.random() * (max - min) ) + min;
}
That will return a random integer with min included and max excluded. If you add that to your code, the call to your for loop can be something like this:
for (let i = 0; i <= getRndInteger(1, 5); i++) {
Hope it helped!
Hint: You should always provide a smaller version of your code, the minimun to understand what you are asking.
I assume you want to randomize the number of loopings with for. So doing following steps:
//Add code to generate a random number
const random = (min, max) => Math.floor(Math.random() * (max - min)) + min;
//Modify thel clearIntervl line:
if (count == random) clearInterval(interVal);

How to find minimum value in an array created in other function?

I created a program which I display the array from input numbers by clicking the button "Add"(which have function "Push"). Then I created another button "What is minimum?" to find the minimum numbers among those and display it by function " Findmin"
But when I console it in Google it had the error Minimum is not defined
How can I access the array created in the function "Push" and use in function " Findmin" ?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Find Minimum Number</title>
</head>
<body>
<div>
<h3><b>Find Minimum Number</b></h3>
</div>
Number add to Array:<input type="text" id="num" name="inputNumber">
<button onclick="Push()">Add</button>
<br>Array Number is:&nbsp<span id="result"></span>
<br><button onclick="Findmin()">What is minimum?</button>
<span id="Min"></span>
<script>
const array = [];
const Min = document.querySelector("#Min");
function Push()
{
let x = document.querySelector("#result");
array.push(document.querySelector("#num").value);
x.textContent = `[`+array+`]`;
}
function Findmin(array)
{
let minimum = array[0];
for (let i =0; i<array.length; i++)
{
if(minimum > array[i]) minimum = array[i];
}
return minimum
Min.textContent = minimum;
}
</script>
</body>
</html>
Edit : I changed the arg passed in Findmin() to "array" . Now I have the error Cannot read property '0' of undefined at this code let minimum = array[0]; I still think the problem it is I don't know how to access in the array created in the first function not the const array = []
Edit2 After all I think I have found my solution . My code work very well even if I input 2 same numbers to the array. For example : I input 34,34,567,9 then the result will return 9. I will post my changed code here. If anyone have any idea on how to make my code easier to read then you're very welcome!
function Findmin()
{
let minimum = document.querySelector("#num").value[0];
for (let i =0; i<document.querySelector("#num").value.length; i++)
{
if(minimum >= document.querySelector("#num").value[i])
minimum = document.querySelector("#num").value[i];
}
Min.textContent = minimum;
I think this will be a easier approch
const array = [];
const Min = document.querySelector("#Min");
function Push() {
let x = document.querySelector("#result");
array.push(document.querySelector("#num").value);
x.textContent = `[` + array + `]`;
}
function Findmin() {
Min.textContent = Math.min(...array.map(Number));
}
<div>
<h3><b>Find Minimum Number</b></h3>
</div>
Number add to Array:
<input type="text" id="num" name="inputNumber" />
<button onclick="Push()">Add</button>
<br /> Array Number is:&nbsp
<span id="result"></span>
<br />
<button onclick="Findmin()">What is minimum?</button>
<span id="Min"></span>
You return minimum before setting Min's textContent to minimum. Returning exits the function - further code is not executed.
Instead, set the textContent before returning:
const array = [];
const Min = document.querySelector("#Min");
function Push() {
let x = document.querySelector("#result");
array.push(document.querySelector("#num").value);
x.textContent = `[` + array + `]`;
}
function Findmin(arr) {
let minimum = array[0];
for (let i = 0; i < array.length; i++) {
if (minimum > array[i]) minimum = array[i];
}
Min.textContent = minimum;
return minimum
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Find Minimum Number</title>
</head>
<body>
<div>
<h3><b>Find Minimum Number</b></h3>
</div>
Number add to Array:<input type="text" id="num" name="inputNumber">
<button onclick="Push()">Add</button>
<br>Array Number is:&nbsp<span id="result"></span>
<br><button onclick="Findmin()">What is minimum?</button>
<span id="Min"></span>
</body>
</html>
you did it very will actually
but your problem is that you return minimum before Min.textContent = minimum
another good way is to use sort the select first index 0
const array = [];
const Min = document.querySelector("#Min");
function Push()
{
let x = document.querySelector("#result");
array.push(document.querySelector("#num").value);
x.textContent = `[`+array+`]`;
}
function Findmin(arr)
{
let minimum = (array.sort((a, b) => a - b))[0];
Min.textContent = minimum;
return minimum
}
<div>
<h3><b>Find Minimum Number</b></h3>
</div>
Number add to Array:<input type="text" id="num" name="inputNumber">
<button onclick="Push()">Add</button>
<br>Array Number is:&nbsp<span id="result"></span>
<br><button onclick="Findmin()">What is minimum?</button>
<span id="Min"></span>
function Findmin(arr)
{
Min.textContent = Math.min(...arr);
}
For more information =>
https://medium.com/#vladbezden/how-to-get-min-or-max-of-an-array-in-javascript-1c264ec6e1aa

Random number generator wont work with parseInt?

I've got this function that does a random number between 100 and 1 in JS and it adds it to the Score keeper, but the score keeper wont work. I even added parseInt for it to convert it from a string to an actually numbers int but it gives me NaN. But when I remove parseInt it gives me stacked numbers. Example: 50 + 100 will become 50100 not 150. Is there something wrong with the code? Here is the HTML and JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="pets.css">
</head>
<body>
<div>
<h1>Score Keeper</h1>
<button onclick="randGen()">Random Numbers</button>
<p id="paragraph"></p>
</div>
<h2 id="score"></h2>
<script src="pets.js"></script>
</body>
</html>
const scoreKeeper = document.getElementById('score');
scoreKeeper = 0;
function randGen() {
const p = document.getElementById('paragraph');
const generatedNumber = Math.floor(Math.random() * 100) + 1;
let currentNumber = parseInt(scoreKeeper.innerText) ?? 0
if (generatedNumber > 0) {
p.innerHTML = `Your number is: ${generatedNumber}`
currentNumber += generatedNumber;
scoreKeeper.innerText = currentNumber;
return scoreKeeper;
}
}
Its a simple javaScript mistake. You are overwriting const. The aspect of const is that the value can NOT be overwritten. change it to let.
Also, you get an element document.getElementById("score") but then automatically overwrite it as 0. Also also, doing parseInt(scoreKeeper.innerText) ?? 0 checks if you can parseInt the innerText rather then if the innerText exist. You should check if it exist first and then parseInt it.
let scoreKeeper = document.getElementById("score");
function randGen() {
let p = document.getElementById("paragraph");
const generatedNumber = Math.floor(Math.random() * 100) + 1;
let currentNumber = scoreKeeper.innerText
? parseInt(scoreKeeper.innerText)
: 0;
if (generatedNumber > 0) {
p.innerHTML = `Your number is: ${generatedNumber}`;
currentNumber += generatedNumber;
scoreKeeper.innerText = currentNumber;
}
}
Also, the return in this case in not needed. You do not return a value to any other function or place. You are modifying your h2 and p inner text directly from the function.
EDIT
You can make the code more readable and using less global variables by making an if check to check if the value is what you do not want and just do an empty return, and move the let scoreKeeper inside the function. Declare all other variables, besides the generatedNumber, after the check and return to only create variables and use up memory if the conditions are met.
function randGen() {
const generatedNumber = Math.floor(Math.random() * 100) + 1;
if (generatedNumber <= 0) return;
let scoreKeeper = document.getElementById("score");
let p = document.getElementById("paragraph");
let currentNumber = scoreKeeper.innerText
? parseInt(scoreKeeper.innerText)
: 0;
p.innerHTML = `Your number is: ${generatedNumber}`;
currentNumber += generatedNumber;
scoreKeeper.innerText = currentNumber;
}

show random number < 0.8 not working properly

Hi I'm kinda new on JS so I tried to do this, I made this to test the random function and I want to show only random numbers below 0.8, but sometimes it shows above 0.8 also more than one time in a row, how do I fix it ?
This is my first post ever here, so sorry if I did something wrong.
Thanks. :)
function rn() {
var a = Math.random()
return a
}
function writerandon() {
var x = 0
while (x < 100) {
if (rn() < 0.8) {
document.write(rn() + "<br>")
}
if (rn() > 0.8) {
x = 100
}
x++
}
}
//
document.getElementById("11").innerHTML = writerandon()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>exp</title>
</head>
<body id="bd">
<h1 id="11"></h1>
</body>
<script src="exp.js"></script>
</html>
Your code makes two random number calls, each of which may have a different value. The fix is to use else to ensure only one branch fires:
let n = Math.random();
if (n < 0.8) {
document.write(n + "<br>")
}
else {
x = 100
}
Just because you've wrapped Math.random() in a function doesn't mean it fires only once. Each and every call to rn() will return a new value. The local variable a is initialized anew with each function call. It does not persist between calls.
In your original code around 16% of the time (80% x 20%) you'd fluke out and trigger both branches.
Assign the return value to a variable in order to hold the same value over different conditions.
function rn() {
var a = Math.random()
return a
}
function writerandon() {
var x = 0
while (x < 100) {
const randomNumber = rn();
if (randomNumber < 0.8) {
document.write(randomNumber + "<br>")
}
if (randomNumber > 0.8) {
x = 100
}
x++
}
}
//
document.getElementById("11").innerHTML = writerandon()
The problem is that you're calling rn() multiple, and it returns different numbers each time. The result you test in if is not the same one that you display with document.write(), or the one that you test in the second if.
You need to save the number to a variable so you can test and display the same number.
Also, use else when you want to do something when the previous test failed.
function rn() {
var a = Math.random()
return a
}
function writerandon() {
var x = 0
while (x < 100) {
var num = rn();
if (num < 0.8) {
document.getElementById("bd").innerHTML += (num + "<br>")
} else {
break;
}
x++
}
}
//
document.getElementById("11").innerHTML = writerandon()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>exp</title>
</head>
<body id="bd">
<h1 id="11"></h1>
</body>
<script src="exp.js"></script>
</html>

finding Middle element of an array in javascript

I need to write a program that finds the middle of an array and returns the value stored there unless the array is even then it should return the average of the two middle most numbers. Here is the code i have so far. i'm stuck on how i would find the middle two numbers in an even array and return the average. I'm a super beginner in java script so all help is appreciated. Thanks!
<!DOCTYPE HTML>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>Add Ends</title>
<script language="javascript" type="text/javascript">
/*
Write a function named getMiddle that returns the value of the middle element in an array. If the array has an even number of elements, then this function must return the average of the two middle elements.
*/
var testNumbers = [0, 1 ,2, 3, 4, 5, 6, 7, 8, 9]
function isEven()
{
var mid = (testNumbers[0] + (testNumbers.length)) / 2;
}
function getMiddle(list)
{
var mid = (testNumbers[0] + (testNumbers.length)) / 2;
if (mid % 2 == 0)
{
var evenMid = isEven();
document.getElementById("outputDiv1").innerHTML = evenMid;
}
else
{
document.getElementById("outputDiv1").innerHTML = mid;
}
}
</script>
</head>
<body>
<button type="button" onclick="binarySearch()">Find the Middle</button>
<br>
<div id="outputDiv1"></div>
</body>
</html>
This should get you somewhere (from this SO answer):
if (nums.length %2 == 0) {
// even-length array (two middle elements)
var avg = (nums[(nums.length/2) - 1] + nums[nums.length/2]) /2;
}
Try the following:
/*
Write a function named getMiddle that returns the value of the middle element in an array. If the array has an even number of elements, then this function must return the average of the two middle elements.
*/
var testNumbers = [0, 1 ,2, 3, 4, 5, 6, 7, 8, 9]
function output(){
var mid = getMiddle(JSON.parse(document.getElementById("lst").value));
outputDiv1.innerHTML = mid;
}
function getMiddle(list)
{
if(list.length % 2 == 1){
return list[(list.length-1)/2];
}else{
return (list[(list.length/2)]+list[(list.length/2 -1)])/2
}
}
<!DOCTYPE HTML>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>Add Ends</title>
</head>
<body>
<input id="lst">
<button type="button" onclick="output()">Find the Middle</button>
<br>
<div id="outputDiv1"></div>
</body>
</html>
var idx = (testNumbers.length-1) / 2;
document.getElementById('outputDiv1').textContent =
( testNumbers[Math.floor(idx)] + testNumbers[Math.ceil(idx)] )/2;

Categories

Resources