Say you have the number var n = 1,000,000;
I want to check:
n >= 1e3
n >= 1e4
n >= 1e5
n >= 1e6
Doing it exactly as it looks above will cause the statement to return true on the first valid expression, obviously. Which means that it will say n is greater than 1e3 and return the results from there.
How can I get it to instead 'cascade' through the expressions until it hits a false, then use the last statement that was true, without having to go:
if( n >= 1e3 && n >= 1e4 && n >= 1e5 && n >= 1e6 ) {...
You should check the number from the biggest to the smalest:
var n = 1000000;
var r = document.getElementById("result");
if (n >= 1e6) r.innerHTML = "n >= 1e6";
else if (n >= 1e5) r.innerHTML ="n >= 1e5";
else if (n >= 1e4) r.innerHTML ="n >= 1e4";
else if (n >= 1e3) r.innerHTML = "n >= 1e3";
<div id="result"></div>
If you need to have all the diffent sentences, you can do:
var r = document.getElementById("result");
var n = 1000000;
var str = "";
if (n >= 1e6) str += "n >= 1e6 ";
if (n >= 1e5) str += "n >= 1e5 ";
if (n >= 1e4) str += "n >= 1e4 ";
if (n >= 1e3) str += "n >= 1e3 ";
r.innerHTML = str;
<div id="result"></div>
To have something more maintainable and extendable :
var n = 1000000;
var r = document.getElementById("result");
check(n, [1000, 1e4, 1e5, 1e6]);
function check(nb, limits) {
limits.sort(function(a, b){return b-a});
var limitsLength = limits.length;
for (var i =0;i<limitsLength;i++) {
if (nb >= limits[i]) r.innerHTML += "n >= 1e" + Math.log10(limits[i]) + " ";
}
}
<div id="result"></div>
No need for branching.
function yours() {
if (n < 1) return 'n is less than 1e0';
return 'n is greater than 1e' + Math.log10(n);
}
If you must branch (for example if you are actually calculating something more complex than a simple logarithm), add a new function to avoid the "cascading" you mention. The return statements will prevent cascading. The new function defines how much stuff gets skipped.
function yours() {
println(figure(n));
}
function figure(n) {
if (n > 10000) return 'n is greater than 1e4';
if (n > 1000) return 'n is greater than 1e3';
if (n > 100) return 'n is greater than 1e2';
if (n > 10) return 'n is greater than 1e1';
if (n > 1) return 'n is greater than 1e0';
}
I'm using println here as a substitute for whatever you want to do with the result.
Related
I had this JavaScript exercise from jshero.net:
Write a function addWithSurcharge that adds two amounts with surcharge. For each amount less than or equal to 10, the surcharge is 1. For each amount greater than 10 and less than or equal to 20, the surcharge is 2. For each amount greater than 20, the surcharge is 3. The call addWithSurcharge(10, 30) should return 44.
My solution was :
function addWithSurcharge (a,b){
let myS = a+b
if (myS <10){
return myS +=2} else if (myS >10 && myS <=20){
return myS +=2} else if (myS >20 && myS <30){
return myS +=3} else if (myS >= 30 && myS <40){
return myS +=4} else if(myS >40){
return myS +=5}
}
Somehow it worked, I passed the challenge but I feel like there was an easier way to solve this. Do you know other alternative answers for this exercise?
you could write it as a switch statement. something like this:
function addWithSurcharge (a,b) {
let myS = a+b
switch (true){
case myS < 10:
return myS + 2
case (myS > 10 && myS <= 20):
return myS + 2
case (myS > 20 && myS < 30):
return myS + 3
case (myS >= 30 && myS < 40):
return myS + 4
default:
return myS + 5
}
}
I think you can round to the superior decade and then divide by 10.
I'm surprised you passed the test cause you don't really fit the problem, you forgot every case when equal to 10, 20, 30, ...
By the way, this is my way to answer your problem. With this way it's "infinite" but if you wan't stop adding after 40, just add Math.max(X, (decadeRounded / 10)) where X is your maximum, for example Math.max(5, (decadeRounded / 10))
function addWithSurcharge (a,b) {
let myS = a + b
let decadeRounded = Math.round( (myS/10) ) * 10;
return myS + (decadeRounded / 10);
}
document.getElementById('result').innerHTML = addWithSurcharge(10, 20);
<div id="result"></div>
You can try something like this
function addWithSurcharge(a, b) {
if (a <= 10) {
a += 1
} else if (a > 10 && a <= 20) {
a += 2
} else if (a > 20) {
a += 3
}
if (b <= 10) {
b += 1
} else if (b > 10 && b <= 20) {
b += 2
} else if (b > 20) {
b += 3
}
return a + b;
}
function addWithSurcharge(a, b) {
i = 0;
if (a <= 10) {
i = i + 1;
} else if (a > 10 && a <= 20) {
i = i + 2;
} else if (a > 20) {
i = i + 3;
}
if (b <= 10) {
i = i + 1;
} else if (b > 10 && b <= 20) {
i = i + 2;
} else if (b > 20) {
i = i + 3;
}
return a + b + i;
}
I can't get theright result, "Weird" on stdin, 18 and 20. Everything looks good to me, however something must be off.
if (N % 2 == 1) {
console.log("Weird");
}
else if ((N % 2 == 0) && (2 >= N <= 5)) {
console.log("Not Weird");
}
else if ((N % 2 == 0) && (5 <= N <= 20)) {
console.log("Weird");
}
else if ((N % 2 == 0) && (N > 20)) {
console.log("Not Weird");
}
else {
console.log("Weird");
}
'use strict';
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let inputString = '';
let currentLine = 0;
process.stdin.on('data', inputStdin => {
inputString += inputStdin;
});
process.stdin.on('end', _ => {
inputString = inputString.replace(/\s*$/, '')
.split('\n')
.map(str => str.replace(/\s*$/, ''));
main();
});
function readLine() {
return inputString[currentLine++];
}
function main() {
const N = parseInt(readLine(), 10);
if (N%2==1) {
console.log("Weird");
}
else if ((N % 2 == 0) && (2 >= N <= 5)) {
console.log("Not Weird");
}
else if ((N % 2 == 0) && (5 <= N && N <= 20)) {
console.log("Weird");
}
else if ((N % 2 == 0) && (N > 20)) {
console.log("Not Weird");
}
else{
console.log("Weird");
}
}
I ve added the whole code. In the main function, in the second else if condition, there seems to be the problem. When n is given 18 or 20, I can not get the right output which should be "Weird"
You can't be doing two conditions in the same time
if (5<=N<=20) {}
Will evaluate 5<=N first which produces either true/false which are when compared to numbers will evaluate to (1/0) respectively. Then the second part ( <= 20) will be evaluated.
Combine two conditions only with AND / OR operators
if (5 <= N && N <= 20) {}
This will solve your problem.
So I am currently working on that function
const countSixes = n => {
if (n === 0) return 0;
else if (n === 1) return 1;
else n = (countSixes(n-1) + countSixes(n-2)) / 2;
return n;
}
And so my question is how to convert the final floating-point value into a string?
Every time after calling the function and trying to convert the float number it returns NaN
What I've Tried
"" + value
String(value)
value.toString()
value.toFixed(2)
Hope to get the answer
Thank you!
The first option works for me
<script>
const countSixes = n => {
if (n === 0) return 0;
else if (n === 1) return 1;
else n = (countSixes(n-1) + countSixes(n-2)) / 2;
return n;
}
alert(countSixes(12) + "")
</script>
The problem is really interesting. Its return NaN because when you return n as String, as the function is called recursively so it cannot perform arithmetic operations in next level.
It will never end for certain numbers like 55
function countSixes(n,firstTime=true){
if (n === 0) return 0;
else if (n === 1) return 1;
else n = (countSixes(n-1,false) + countSixes(n-2,false)) / 2;
if(firstTime) return n.toFixed(10); // return string
else return parseFloat(n.toFixed(10)); // return float
}
You could convert the final value to a string with the wanted decimals.
const countSixes = n => {
if (n === 0) return 0;
if (n === 1) return 1;
return (countSixes(n - 1) + countSixes(n - 2)) / 2;
}
console.log(countSixes(30).toFixed(15));
I'm a beginner and trying to complete a prime number test but I'm running into an issue. Here is what I have:
var n = Number(prompt("Input the number you want to check for prime:"));
var i;
if (n < 2) {
alert(n + " is not a prime number.");
}
for (var i = 2; i <= Math.sqrt(n); i++) {
if (n % i === 0) {
alert(n + " is not a prime number.");
break;
}
else {
alert(n + " is a prime number.");
break;
}
}
It's running correctly except an alert won't pop up if I input 3 or 2 and any number with a 3 in it is coming back as a prime number even if it isn't. Other than that all of my tests have worked.
Ahhh, your problem is the way you've structured the loop. You're breaking out regardless of if the check's completed.
var n = Number(prompt("Input the number you want to check for prime:"));
var i;
var isPrime = true;
if (n < 2) {
isPrime = false;
} else if (n < 4 && n >= 2) {
// isPrime is already true
} else if (n % 2 === 0) {
isPrime = false; // no divisor of 2 can be prime
} else {
var sqrtN = Math.sqrt(n);
for (var i = 3; i <= sqrtN; i = i + 2) {
if (n % i === 0) {
// Only break out of the loop if a match is found
isPrime = false;
break;
}
}
}
if (isPrime) {
alert(n + " is a prime number.");
} else {
alert(n + " is not a prime number.");
}
Or, a perhaps more organized solution:
function isPrime (n) {
n = parseInt(n);
var i;
if (Number.isNaN(n)) {
return false;
} else if (n < 2) {
// 1 is not prime
return false;
} if (n < 4) {
// 2 and 3 are prime, so why not skip checking them?
return true;
} else if (n % 2 === 0) {
// No number divisible by 2 is prime.
return false;
} else {
// This won't change, so calculate it once as suggested by Weather Vane.
var sqrtN = Math.sqrt(n);
// 4, 6, 8... All divisible by 2, and would be caught by initial check.
for (i = 3; i < sqrtN; i = i + 2) {
// Not a prime if it's evenly divisible.
if (n % i === 0) {
return false;
}
}
// Otherwise prime.
return true;
}
}
Of course. If n % i is not 0, it means that i does not divide n, but it does not mean n is prime. You must check all i in order to say that.
Moreover, don't recalculate expensive Math.sqrt(n) at each iteration. And be aware of NaN.
var n = Number(prompt("Input the number you want to check for prime:"));
function isPrime(n) {
if (n < 2 || !n) return false;
for (var i = 2; i*i <= n; i++) {
if (n % i === 0) return false;
}
return true;
}
alert(n + " is " + (isPrime(n) ? "" : "NOT ") + "a prime number.");
Of course, this algorithm is exponential (pseudo-polynomial). Don't use it for big n. Instead, see e.g. Miller–Rabin primality test or AKS primality test, which are polynomial.
var UI = window.prompt("Enter a whole number to test as a prime number: \n", "0");
var TV = parseInt(UI, 10);
var HITS = 0;
var DD = TV;
while (DD > 0) {
if (TV % DD === 0) {
HITS++;
}
DD--;
}
if (HITS > 2) {
document.write(UI + " is a NOT prime number");
} else {
document.write(UI + " is a prime number");
}
Please have reference to old questions asked in stackoverflow
link to the old question
function num(n) {
if (n >= 1000 && n < 10000) return (n/1000).toFixed(3) + "K";
if (n >= 10000 && n < 100000) return (n/1000).toFixed(1) + "K";
if (n >= 100000 && n < 1000000) return (n/1000).toFixed(0) + "K";
if (n >= 1000000 && n < 10000000) return (n/1000000).toFixed(3) + "M";
if (n >= 10000000 && n < 100000000) return (n/1000000).toFixed(1) + "M";
if (n >= 100000000 && n < 1000000000) return (n/1000000).toFixed(0) + "M";
if (n >= 1000000000 && n < 10000000000) return (n/1000000000).toFixed(3) + "B";
if (n >= 10000000000 && n < 100000000000) return (n/1000000000).toFixed(1) + "B";
if (n >= 100000000000 && n < 1000000000000) return (n/1000000000).toFixed(0) + "B";
if (n >= 1000000000000 && n < 10000000000000) return (n/1000000000000).toFixed(3) + "T";
if (n >= 10000000000000 && n < 100000000000000) return (n/1000000000000).toFixed(1) + "T";
if (n >= 100000000000000 && n < 1000000000000000) return (n/1000000000000).toFixed(0) + "T";
return n;
}
Since at some point I'm probably going to be going upwards to the power of hundreds, is there an easier way to do this?
function formatNumber(number) {
var i = 0; units = [ "", "K", "M", "B", "T" ]; // etc
while (number > 1000) {
number /= 1000;
i += 1;
}
return Math.floor(number * 1000) / 1000 + units[i];
}
formatNumber(1234567); // 1.234M
formatNumber(1230567); // 1.23M
This might be faster for very large numbers:
function formatNumber(number) {
var i; units = [ "", "K", "M", "B", "T" ]; // etc
i = Math.round(Math.log(number) / Math.log(10) / 3);
number /= Math.pow(10, i * 3);
return Math.floor(number * 1000) / 1000 + units[i];
}
formatNumber(1234567); // 1.234M
formatNumber(1230567); // 1.23M
My approach here:
function num(n) {
if(n < 1000) {
return n
}
var units = ['K', 'M', 'B', 'T']
for(var i = -1; n >= 1000; i++) {
n /= 1000
}
if(n >= 100) {
return n.toFixed(0) + units[i]
}
if(n >= 10) {
return n.toFixed(1) + units[i]
}
return n.toFixed(3) + units[i]
}
Here's the finished function with help from Halcyon.
function fnum(number) {
var i, x, units = [ "", "K", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc", "No", "Dc" ];
i = Math.floor(Math.log(number) / Math.log(10) / 3);
x = Math.floor(Math.log(number) / Math.log(10)) % 3;
number /= Math.pow(10, i * 3);
return ((number * 1000) / 1000).toFixed(77 % ((x * 2) + 3)) + units[i];
}
Will return a number from 0 to 999 to 2 decimal places when formatted to 1s and 10s, and 0 decimal places when formatted to 100s, and then add a numerical suffix. Add additional suffixes as required.
fnum(22000); >> 22.00K
fnum(153000000); >> 153M
fnum(2,230,000,000,000); >> 2.23T
function fnum(number) {
var i, x, units = [ "", "K", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc", "No", "Dc" ];
i = Math.floor(Math.log(number) / Math.log(10) / 3);
x = Math.floor(Math.log(number) / Math.log(10)) % 3;
number /= Math.pow(10, i * 3);
return ((number * 1000) / 1000).toFixed(77 % ((x * 2) + 3)) + units[i];
}
console.log(fnum(22000))
console.log(fnum(153000000))
console.log(fnum(2200000000000))