Javascript find max number from 3 inputs - javascript

I've just began Javascript in college. One task is to define and call a function to find the maximum number from 3 numbers entered by the user. I know there is a max() function but we were told to do it manually using if and else if.
I'm going wrong somewhere as you can see. It's just telling me the max is 0 everytime.
function maxNum(num1, num2, num3){
var max = 0;
if(num1 > num2){
if(num1 > num3){
num1 = max;
}
else{
num3 = max;
}
}
else{
if(num2 > num3){
num2 = max;
}
}
return max;
}
for(i=0;i<3;i++){
parseInt(prompt("Enter a number"));
}
document.write(maxNum());

Or you can use ES6 syntax, to compute largest of three numbers in easier way,
const largest = a => F = b => G = c => ((a > b && a > c) ? a : (b > a && b > c) ? b : c)
console.time()
console.log(largest(53)(30907)(23333))
console.timeEnd()

One problem you have is that you do not save the number the user inputs. You prompt them, parse it as an int and then nothing. You have to pass the 3 numbers into maxNum()
Here is a working example that uses proper left hand assignment and saves the number. Also it is a good idea to use >= instead of > because the user can enter 2 of the same number
function maxNum(num1, num2, num3){
var max = 0;
if((num1 >= num2) && (num1 >= num3)){
max = num1;
}
else if((num2 >= num1) && (num2 >= num3)){
max = num2;
}
else{
max = num3;
}
return max;
}
var arr = [];
for(i=0;i<3;i++){
arr[i] = parseInt(prompt("Enter a number"));
}
document.write(maxNum.apply(this, arr));

easiest way:
function maxNum(num1, num2, num3){
var tmp = 0;
if(num1 < num2 && num3 < num2) {
tmp = num2;
} else if(num3 < num1){
tmp = num1;
} else {
tmp = num3;
}
return tmp;
}
var arr = [];
for(var i = 0; i < 3; i++) {
arr[i] = prompt("Enter a number");
}
console.log(maxNum.apply(this, arr));

First in javascript and most modern programming language assignment like a = b copies the value of b into the variable a. It is not equivalent to b = a (which copies the value of a into the variable b). It's common to write a = 1, but a syntax error in most languages to write 1 = a. Thus, you don't want to write num1 = max, but instead write max = num1.
Second, your logic is incorrect as it won't treat the case maxNum(1,2,3) correctly. (Work through the logic when num1 < num2 and num2 < num3. The following code would work:
function maxNum(num1, num2, num3){
var max = 0;
if(num1 > num2){
if(num1 > num3){
max = num1;
}
else{
max = num3;
}
}
else{
if(num2 > num3){
max = num2;
} else {
max = num3;
}
}
return max;
}
Granted, I would probably write something like
function max3num(num1, num2, num3) {
var max_so_far = num1;
if (num2 > max_so_far) {
max_so_far = num2;
}
if (num3 > max_so_far) {
max_so_far = num3;
}
return max_so_far;
}
as the logic is very clear and it will be easy to extend to a max function with a larger number of elements to compare if necessary. (Adding in a for loop could make it variadic fairly easily). It is straightforward to see the logic works, because we start with the first element being the maximum so far (max_so_far), then consider if the second element is larger -- if so we assign that as max_so_far, and keep continuing until we have compared all the elements to the max_so_far. After we have considered each element once, we then return the max_so_far which will now be the maximum of all of them.

No real need for a function here, just compare them as the come in!
var max = 0;
for(var i=0;i<3;i++){
var val = parseInt(prompt("Enter a number"));
max = max > val ? max : val;
}
alert(max);

The updated direct answer is this :
function maxNum(num1, num2, num3){
return [num1, num2, num3].sort(function (a, b) { return b - a })[0];
}
If written like this, it can easily be modified to take any amount of numbers by passing it an array of said numbers.
var numArray = [num1, num2, num3, num4, ...];
function maxNum(numArray){
return numArray.sort(function (a, b) { return b - a })[0];
}
The details :
Take an array :
[5,42,16]
Now sort it.
[5,42,16].sort()
But this wont work because javascript .sort requires a function to be passed in. This function tells it how to sort the array.
This will sort it highest to lowest, e.g. a is less then b.
function (a, b) { return b - a }
This will sort it lowest to highest, e.g. b is less then a.
function (a, b) { return a - b }
So we add it in :
[5,42,16].sort(function (a, b) { return b - a })
But this returns the sorted array, not the maximum number.
So we pick the first element in the array :
[5,42,16].sort(function (a, b) { return b - a })[0]
Lastly, you can pull out the sort function. This is mostly for demo purposes though.
var maxSorter = function (a, b) { return b - a };
function maxNum(numArray){
return numArray.sort(maxSorter)[0];
}

//Raihan
// program to find the largest among three numbers
// take input from the user using Prompt
let num1 = parseFloat(prompt("Enter first number: "));
let num2 = parseFloat(prompt("Enter second number: "));
let num3 = parseFloat(prompt("Enter third number: "));
let largest = Math.max(num1, num2, num3);
// display the result
document.write("The largest number is " + largest);
**//another way**
const num1 = parseFloat(prompt("Enter first number: "));
const num2 = parseFloat(prompt("Enter second number: "));
const num3 = parseFloat(prompt("Enter third number: "));
// check the condition
if(num1 >= num2 && num1 >= num3) {
document.write("Largest Number : " + num1)
}
else if (num2 >= num1 && num2 >= num3) {
document.write("Largest Number : " + num2)
}
else {
document.write("Largest Number : " + num3)
}

Related

How to detect math operator on current html page so that my code can assign the correct sum

I have been working on a maths project for my son, and am currently struggling to attach the correct maths sum to the correct math operator currently shown on the website.
The function mathOperator() aims to identify what math operator is currently on page and then supply the correct sum.
Then i am trying to check if the textContent of the chosen clicked answer matches that sum or not using the anonymous function below mathOpertor().
I am getting no errors in the console but the code is annoyingly just adding num1 and num2 together no mater which math operator is currently active.
I figure the problem is within the lines:
let operator = num1 + num2;
if (this.textContent == operator) { }
I figured (let operator) would be mutated to the condition that was met within the mathOperator() function, but this is not the case!
Here is my code below:
//Globals
const arrLength = 10
const randomArr = []
//push random numbers to randomArr.
for (let i=0; i<arrLength; i++) {
randomArr.push(Math.floor(Math.random() * 10));
}
//DOM targets
//first and second numbers.
const num1 = document.getElementById("num1").textContent = randomArr[0];
const num2 = document.getElementById("num2").textContent = randomArr[1];
//Multiple choice answers
let option1 = document.getElementById("option1").textContent = randomArr[2];
let option2 = document.getElementById("option2").textContent = randomArr[3];
let option3 = document.getElementById("option3").textContent = randomArr[4];
//Places the correct asnwer randomly within the 3 multiple choice answers.
const correctAnswerPosition = Math.floor(Math.random() * 3);
document.querySelectorAll(".options h1")[correctAnswerPosition].textContent = num1 + num2;
//function to decide how to calculate equation depending on what HTMLpage you are on.
function mathoperators(sum) {
if (document.querySelector(".wrapper div").children[1].textContent == "+") {
sum = num1 + num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "-") {
sum = num1 - num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "*") {
sum = num1 * num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "/") {
sum = num1 / num2;
}
}
//What do to if you pick right or wrong answer.
for (let a=0; a<document.querySelectorAll(".options").length; a++) {
//targets the 3 divs that contain random incorrect answers plus correct answer.
document.querySelectorAll(".options")[a].addEventListener("click", function() {
let operator = num1 + num2;
if (this.textContent == operator) { //problem here i don't know how to connect this to sum in math operators function.
const correct = new Audio("Sounds/correct.mp3");
correct.play();
document.querySelector(".wrapper").style.display="none";
document.querySelector(".well-done").style.display="block";
setTimeout(function() {
location.reload();
}, 3000);
} else {
const incorrect = new Audio("Sounds/incorrect.mp3");
incorrect.play();
}
mathoperators(operator)
})
}
function reload() {
reload = location.reload();
}
Thankyou for your time in advance.
# bergi, Thanks very much this is the push in the right direction I needed, the changes have been made below:
function mathoperators() {
if (document.querySelector(".wrapper div").children[1].textContent == "+") {
return num1 + num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "-") {
return num1 - num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "*") {
return num1 * num2;
} else if (document.querySelector(".wrapper div").children[1].textContent == "/") {
return num1 / num2;
}
}
//What do to if you pick right or wrong answer.
for (let a=0; a<document.querySelectorAll(".options").length; a++) {
document.querySelectorAll(".options")[a].addEventListener("click", function() {
const number = parseFloat(this.textContent)
if (mathoperators() === number) {
const correct = new Audio("Sounds/correct.mp3");
correct.play();
document.querySelector(".wrapper").style.display="none";
document.querySelector(".well-done").style.display="block";
After this I also noticed that the below needed changing so that it was equal to mathOperator() and not num1 + num2;.
//Places the correct asnwer randomy within the 3 multiple choice answers.
const correctAnswerPosition = Math.floor(Math.random() * 3);
document.querySelectorAll(".options h1")[correctAnswerPosition].textContent = mathoperators();
Thanks for your help Bergi.

How can I make this code find amicable numbers in a determined range in javaScript?

I want to have a code that finds amicable numbers in a certain range, but it only outputs one amicable number instead of all amicable numbers in that range.
How can I solve it? I think it may be a scope error.
Amicable numbers are a pair of numbers that the sum of all the divisors of the first number equals the second number, and the sum of the divisors of the second number equals the first number.
Here is my code:
let sum1 = 1;
let sum2 = 1;
for (let num1 = 3; num1 < 1300; num1++) {
for (let num2 = 3; num2 < 1300; num2++) {
for (let div1 = 2; div1 < num1; div1++) {
if (num1 % div1 === 0) {
sum1 += div1
}
}
for (let div2 = 2; div2 < num2; div2++) {
if (num2 % div2 === 0) {
sum2 += div2
}
}
if (num1 === sum2 && sum1 === num2) {
console.log(num1 + " and " + num2 + " are amicable numbers!")
}
}
}
Your code is very inefficient, having to calculate the sum of the divisors on every iterartion - even though you have previously calculated the sum of divisors for this number.
I tend to find it easier to think about this sort of problem in multiple steps. Step 1, calculate the sum of divisors for any given number:
const sumDivisors = num => {
let res = 0;
for(let i=1;i<num;i++)
if( (num % i) == 0)
res += i
return res;
}
Step 2, gather the numbers in the desired range and all their sums of divisors
var divisors = new Array(1300).fill(0).map( (_,i) => i)
.reduce( (acc,num) => ({...acc, [num]: sumDivisors(num)}))
The above gives you an object with num as the key and sum (of divisors) as the value.
{
"1": 0,
"2": 1,
"3": 1,
"4": 3,
"5": 1,
"6": 6,
"7": 1,
"8": 7,
.. etc
}
Step3, look for any item in the list where
key less than value (this also covers key != value and stops you getting both ways in the result ie 220,284 & 284,220)
value matches another key
Put it all together you get the below code which gives the expected results
const sumDivisors = num => {
let res = 0;
for(let i=1;i<num;i++)
if( (num % i) == 0)
res += i
return res;
}
var divisors = new Array(1300).fill(0).map( (_,i) => i)
.reduce( (acc,num) => ({...acc, [num]: sumDivisors(num)}))
var amicable = Object.entries(divisors)
.filter( ([num,sum]) => num < sum && divisors[sum] == num);
for(let [num1,num2] of amicable)
console.log(num1 + " and " + num2 + " are amicable numbers!")
You may like to compare the performance difference here between your original code (fixed to work) and the code in this answer: https://jsbench.me/jekosj89v4/1 The improvement in speed is a factor of 1000
Your code is never resets the sums so it will never find a match.
I don't know how to make it very efficient because I don't know about complexity, but here is my algorithm:
First, export the sum of dividers to a function so we can use it for any given number.
Then, loop through the numbers up to 1300 for example and use the function to find the sum of dividers for each number. When you have the sum, this is the number you want to check backwards (if the sum dividers of that number is equal to the original number they are amicable pair), you don't have to check all the numbers because the sum of dividers will give you only one number.
If the sum of dividers is less than the number, we already checked it and found the pair. If the number is equal to the sum it is the same number, this is not a pair.
So this is my final code:
const getDividersSum = (num) => {
let sum = 0;
for (let i = 1; i <= num / 2; i++) {
if (num % i === 0) {
sum += i;
}
}
return sum;
}
for (let num = 3; num < 1300; num++) {
const amicableNum = getDividersSum(num);
if (amicableNum !== num && num < amicableNum) {
if (getDividersSum(amicableNum) === num) {
console.log('Amicable nums: ', num, amicableNum);
}
}
}
I believe you need to move the declarations of sum1 and sum2 inside the second for loop. Check out this fiddle. (Edit: reason is because the sums continue to grow rather than resetting each time.)
Note, I changed a bit of code to ensure that the numbers were distinct (see num1 !== num2 on line 18 of the fiddle) and to avoid repeated pairs (see num2 < num1 rather than num2 < 1300 on line 2 of the fiddle.)

How to calculate the factorial of a number entered by user in Javascript, using, do-loop, while-loop?

Quick follow-up question on my previous question. I'd like to add the code to the following to calculate the factorial of a number entered by user in Javascript.
<!DOCTYPE html>
<html>
<head>
<title>Sum of Numbers</title>
<script>
var numbers = prompt("Enter a number 1-100");
while (numbers!=null && (isNaN(parseInt(numbers)) || parseInt(numbers) >100 || parseInt(numbers) <1)) {
numbers = prompt("Try again.Enter a number 1-100");
}
if (numbers !=null){
alert("Finally you entered a correct number");
var sum = 0;
var numOfLoops = numbers;
var counter = 1;
do {
sum+=counter;
counter++;
}
while (counter<=numOfLoops)
alert ("The sum of numbers from 1 to " + numbers + "is =" +sum);
}
</script>
</head>
<body>
<script>
document.write("<h1>Sum of Numbers</h1>");
document.write("The sum of numbers from 1 to = " + numbers + " is = " +
+ sum + "<br><br>");
</script>
</body>
</html>
If you are trying to sum up the numbers, consider using arithmetic series formula. If you're trying to get the factorial, the approach is shown below.
If you want to sum using the loop, just change the *= to +=.
While Loop Approach
const fact = (n) => {
let res = 1;
while (n > 0) {
res *= n;
n--;
}
return res;
}
fact(5) // 120
Do While Approach
const fact = (n) => {
let res = 1;
do {
res *= n;
n--;
} while (n > 0)
return res;
}
fact(3) // 6
That should do the trick. :)
Maybe also considering checking for edge cases like if the n is negative.
Good luck.
While Loop:
const fact=n=>
{
if(n<0) throw 'factorial error on a negative number!'
let r = 1
while(n) r *= n--
return r
}
Do While:
const fact=n=>
{
if(n<0) throw 'factorial error on a negative number!'
let r = 1
do r *= n || 1 // in case of n == 0
while (n--)
return r;
}
complete code
const
msgPrompt_1 = 'Please enter a number from 0 to 100',
msgPrompt_n = 'Try again.... Enter a number 0-100',
fact = n =>
{
let r = 1
while(n) r *= n--
return r
}
let numValue = parseInt(window.prompt(msgPrompt_1, ''), 10)
while(isNaN(numValue) || numValue > 100 || numValue < 0)
{
numValue = parseInt(window.prompt(msgPrompt_n, ''), 10)
}
alert(`factorial value of ${numValue} is = ${fact(numValue)}` )

javascript user input highest of 20 numbers

for this program, i need the user to enter 20 numbers and for the highest to be displayed. i have done a similar one with 4, which i will display below, however there must be an easier way that going through it all? any advice would be great.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function maxNum(num1, num2, num3, num4){
var max = 0;
if((num1 >= num2) && (num1 >= num3)){
max = num1;
}
else if((num2 >= num1) && (num2 >= num3) && (num3 >= num4)){
max = num2;
}
else if((num3 >= num1) && (num3 >= num2) && (num3 >= num4)){
max = num3;
}
else{
max = num4;
}
return max;
}
var arr = [];
for(i=0;i<4;i++){
arr[i] = parseInt(prompt("Enter a number"));
}
document.write(maxNum.apply(this, arr));
</script>
</body>
</html>
function findMaxNum(arr) {
return Math.max.apply(null, arr);
}
var arr = [];
for (var i = 0; i < 4; i++) {
arr[i] = parseInt(prompt('Enter a number'), 10);
}
var maxNum = findMaxNum(arr);
Math.max usually works with a series of numbers: Math.max(1, 4, 10) // 10, but here we use apply on the function so that it accepts an array instead.
(Note, added the radix for parseInt)
DEMO
Assuming that all values passed into your function will be numbers you can use Math.max with the arguments special variable.
function getMax()
{
if (Object.prototype.toString.call(arguments[0]) === '[object Array]') {
return Math.max.apply(null, arguments[0]);
}
return Math.max.apply(null, arguments);
}
var myArr = [2,4,6,8,10,12,14,16,18,20];
getMax(1,2,4,5,6,7,8,10); // 10
getMax(myArr); // 20
The example above allows an array or a list of arguments to be passed through. This allows you to reuse where required.
Yes, with Math.max.apply. It takes an object (null) and an array with the values.
function getMax(array) {
var i,
max = +array[0]; // the first element with implicit casting to number
for (i = 1; i < array.length; i++) { // loop throu all elements
if (+array[i] > max) { // with cast to number
max = array[i];
}
}
return max;
}
var userInput = ['1', 'a', '4', '-', '1000', '20'].filter(Number);
document.write(userInput + '<br>');
document.write(Math.max.apply(null, userInput) + '<br>');
document.write(getMax(userInput) + '<br>');

Division in javascript

function subtraction(num1, num2){
var num3;
num3 = num1 - num2;
document.writeln("Difference "+ num3);
return (num3);
}
function division(num1, num2){
difference = parseFloat(subtraction());
var x;
while(difference > 0){
difference = num1-num2;
x = x + 1;
}
document.writeln("Quotient" + x);
}
Hi! I wanted to do a division function but the catch is I will not use "/". This is what I got and so far this prints out "undefined" and if I stated x = 0 it will print out "0".
I fixed some problems with your code:
function division(num1, num2){
var difference = num1-num2; // difference is now a local variable
var x = 0; // x should be initialized
while(difference > 0){
difference = difference-num2; // difference should change, not always be num1-num2
x = x + 1;
}
console.log("Quotient" + x);
console.log("Remainder" + (difference+num2));
}
http://jsbin.com/UQIqejo/1/edit
You still have some problems with the algorithm itself, as num2 being less than or equal to 0 will result in an infinite loop, but i expect finding those problems is part of the fun.
EDIT: Smaller version of the same code:
function divisionSmall(a,b) {
var x = 0;
while ((a-=b) > 0) x++;
console.log('Quotient', x);
console.log('Remainder', a+b);
}
EDIT2: Correct division:
function divisionSmall(a,b) {
var x = 0;
while ((a-=b) > 0) x++;
return [x, a+b];
}
function divisionCorrect(a,b) {
var ans;
if (b === 0) return ['INF', 0];
if ((a > 0) && (b > 0)) {
return divisionSmall(a,b);
}
if ((a > 0) && (b < 0)) {
ans = divisionSmall(a,-b);
return [-ans[0], ans[1]];
}
if ((a < 0) && (b > 0)) {
ans = divisionSmall(-a,b);
return [-ans[0] - 1, b-ans[1]];
}
if ((a < 0) && (b < 0)) {
ans = divisionSmall(-a,-b);
return [ans[0] + 1, -b-ans[1]];
}
}
console.log(divisionCorrect(11,3)); // 3, 2
console.log(divisionCorrect(11,-3)); // -3, 2
console.log(divisionCorrect(-11,3)); // -4, 1
console.log(divisionCorrect(-11,-3)); // 4, 1
There is still the challenge of doing the logic without ifs :). Good luck.
If your doing numbers their is a simpler way to do this using recursion:
function divide(num,denom) {
if (num < denom) return 0;
return (1 + divide(num - denom, denom));
}
For negative numbers you would have to extend this to track if numbers were less than 0. Also, while concise and neat, this breaks down for large numerators and small denominators as the max call stack size will be exceeded.
I believe your issue is with your while loop. If the subtraction method returns a negative number it will not compute.
User Math.abs to get absolute value.
<script>
function division(num1, num2){
var difference = Math.abs(parseFloat(subtraction(num1, num2)));
var x = 0;
while(difference > 0){
difference = difference-num2;
x = x + 1;
}
document.writeln("Quotient" + x);
}
function subtraction(num1, num2){
var num3;
num3 = num1 - num2;
document.writeln("Difference "+ num3); return (num3);
}
</script>

Categories

Resources