Learning the basics and had this exercise:
"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, the surcharge is 2. The call addWithSurcharge(5, 15) should return 23."
I had put:
function addWithSurcharge(num1, num2) {
if (num1 <= 10) {
num1 += 1;
} else {
num1 += 2;
}
if (num2 <= 10) {
num2 += 1;
} else {
num2 += 2;
}
return num1 + num2;
}
Which works, but want to learn better syntax. Could something like
if (num1, num2 <= 10) {...
work? I realize can't do the || operator because it could affect the wrong num.
Put the numbers into an array instead, and iterate over the array so you don't have to repeat both the num1 and num2:
function addWithSurcharge(...nums) {
return nums.reduce((a, num) => {
if (num <= 10) {
num += 1;
} else {
num += 2;
}
return a + num;
}, 0);
}
console.log(addWithSurcharge(5, 15));
Without .reduce, the above is equivalent to:
function addWithSurcharge(...nums) {
nums.forEach((num, i) => {
if (num <= 10) {
nums[i] += 1;
} else {
nums[i] += 2;
}
});
return nums[0] + nums[1];
}
console.log(addWithSurcharge(5, 15));
You can use the conditional operator to make the if/else part more concise without bothering with reassignment, too:
const addWithSurcharge = (...nums) => (
nums.reduce(
(a, num) => a + num + (num <= 10 ? 1 : 2),
0
)
);
console.log(addWithSurcharge(5, 15));
You could also do:
function addWithSurcharge(num1, num2) {
return num1 + num2 + num1<=10?1:2 + num2<=10?1:2;
}
The num1<=10?1:2 basically means if(num1<=10){1} else{2} which works really well!
The most basic improvement is a helper function that you can call twice:
function withSurcharge(num) {
if (num <= 10) return num + 1;
else return num + 2;
}
function addWithSurcharge(num1, num2) {
return withSurcharge(num1) + withSurcharge(num2);
}
You could further shorten the if/else statement to use a conditional expression, but not much is gained by that:
return num + (num <= 10 ? 1 : 2);
One way you could do this would be to use the ternary opertator
function addWithSurcharge(num1,num2)
{
num1 += num1 <= 10 ? 1 : 2;
num2 += num2 <= 10 ? 1 : 2;
return num1 + num2;
}
console.log(addWithSurcharge(10,5));
If you use a ? when assigning a value it'll evaluate whatever is on the left hand side of the ? and either return the left hand side of the : if it's true or the right hand side if it's false.
Related
I am currently trying to create a function that increment numbers. The thing is that I would like the function to be able to change the incrementing value each time a "power of ten" is reached. I have a first function that handle the "incrementing value".
Here is what I have so far:
function getInc(num) {
let abs = Math.abs(num);
let inc = Math.pow(10, Math.floor(Math.log10(abs)));
if (abs === num) return inc;
if (num === -10) { return -1; }
if (num === -1) { return -0.1; }
return -inc
}
This works well, except from values likes -10, -0.1.
For : getInc(-0.1) the result should be -0.01, but my current function returns -0.1
I would like to avoid lines like if (num === -10) { return -1; } because I can not handle all the cases this way, but I am a little stuck here.
Thank you in advance.
Edit: this is the rest of the code, the function that actually increments, if this can help understand how the getInc result is used:
if ((num < -1) && (num >= -10) ) {
return Math.floor(Math.round(num) - getInc(num))
}
if ((num <= 0) && (num >= -1) ) {
return num - getInc(num)
}
if (num >= 1 && num < 10) {
return Math.round(Math.floor(num + getInc(num))) ;
}
if ((num >= 10) || (num > 0 && num < 1)) {
const result = Math.ceil(num / getInc(num)) * getInc(num);
if (result === num) { return num + getInc(num) }
else { return result }
}
if (num < -10) {
const result = Math.ceil(num / getInc(num)) * getInc(num) - getInc(num);
if (result === num) { return num + getInc(num) }
else { return result }
}
}
Desired results example:
getInc(-10) : -1
getInc(-4) : -1
getInc(-1) : -0.1
getInc(-0.4) : -0.1
getInc(-0.1) : -0.01
getInc(-0.04) : -0.01
getInc(-0.01) : -0.001
For now I have:
getInc(-10) : -10
getInc(-4) : -1
getInc(-1) : -1
getInc(-0.4) : -0.1
getInc(-0.1) : -0.1
getInc(-0.04) : -0.01
getInc(-0.01) : -0.01
You could check the sign if the log value is an integer.
function getInc(num) {
const
sign = Math.sign(num),
log = Math.log10(Math.abs(num));
return sign * Math.pow(10, Math.floor(log) - (sign === -1 && Number.isInteger(log)));
}
console.log(getInc(9)); // 1
console.log(getInc(10)); // 10
console.log(getInc(-10)); // -1 adjust - 1
console.log(getInc(-4)); // -1
console.log(getInc(-1)); // -0.1 adjust - 1
console.log(getInc(-0.4)); // -0.1
console.log(getInc(-0.1)); // -0.01 adjust - 1
console.log(getInc(-0.04)); // -0.01
console.log(getInc(-0.01)); // -0.001 adjust - 1
.as-console-wrapper { max-height: 100% !important; top: 0; }
your problem are, that numbers, that are already a power of ten are not changed by the expression Math.pow(10, Math.floor(Math.log10(abs))) (because of Math ... if num === power of 10 --> Math.log10(num) === integer (not float) ---> Math.flat() has no effect on integers --> the expression remaining is Math.pow(10, Math.log10(num)) which is the same as just num)
But you want numbers, that already are a power of ten to return a power of ten (but the exponent being one lower as the exponent of num - in easy words, you want the number to get divided by ten)
so at the start of your function you check for numbers, that already are a power of ten ... if that is the case, return the number divided by ten if it is not already a power of ten proceed as it did before.
So your code basically stays the same (you just exit the function early in case of numbers already being a power of ten (and return the number divided by ten)
here's your code with the if clause implemented:
function getInc(num) {
let abs = Math.abs(num);
if (Math.log10(abs) % 1 === 0) return num / 10;
let inc = Math.pow(10, Math.floor(Math.log10(abs)));
if (abs === num) return inc;
return -inc;
}
console.log(getInc(100));
console.log(getInc(4));
console.log(getInc(0.1));
console.log(getInc(-4));
console.log(getInc(-1));
console.log(getInc(-0.4));
console.log(getInc(-0.1));
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 need to write a function which:
Given 2 integers,it returns the product between the two given integers, beginning at num1, and excluding num2. I don't want to use a for loop.
Notes:
* The product between 1 and 4 is 1 * 2 * 3 = 6.
* If num2 is not greater than num1, it should return 0.
var output = multiplyBetween(2, 5);
console.log(output); // --> 24
What I have so far is below:
function multiplyBetween(num1, num2) {
if (isNaN(num1) || isNaN(num2)) return NaN;
if (num1 === 0 || num2 ===0) return 0;
if (num1 === num2) return 0;
if (num2 < num1){
return 0;
}
else{
while(num1<num2){
return num1 * multiplyBetween(num1 + 1, num2 )
}
}
}
What am I doing wrong?
The problem is that when you get to the base case of num1 == num2 you return 0, and then you multiply by the recursive call you multiply by 0, and end up returning 0 in all cases.
You should return 1 in that case rather than 0.
There's also no need for the while loop. First, because you return unconditionally in the loop, it it never repeats. And if it did repeat, it would repeat infinitely because the variables are never changed in the loop.
function multiplyBetween(num1, num2) {
if (isNaN(num1) || isNaN(num2)) return NaN;
if (num1 === 0 || num2 === 0) return 0;
if (num1 === num2) return 1;
if (num2 < num1) {
return 0;
}
return num1 * multiplyBetween(num1 + 1, num2)
}
console.log(multiplyBetween(2, 5));
function multiplyBetween(num1, num2) {
let total = 1;
if (num1 >= num2) {
return 0;
} for (let i = num1; i<num2;i++) {
total*=i;
} return total;
}
multiplyBetween(2, 5);
Here is the code. You can test it for yourself.
Please explain :)
var factorial = 1;
function factorialize(num) {
factorial *= num;
if (num == 1) {
var result = factorial;
return result;
}
factorialize(num-1);
}
factorialize(5);
It needs no global variable and no local variable, too.
function factorialize(num) {
if (num === 1) {
return 1;
}
return num * factorialize(num - 1);
}
console.log(factorialize(5));
// or a very short version:
function f(n) { return +!~-n || n * f(n - 1); }
console.log(f(10));
You don't need some variables if you use recursion. That's one of the most interesting things about recursion.
Take a look at this much shorter recursive solution:
function factorial(n)
{
return (n === 1) ? 1 : n * factorial(n - 1);
}
for (var i = 1; i <= 7; i++)
document.getElementById("myDiv").innerHTML += (i + "! = " + factorial(i) + "<br/>");
<div id="myDiv">
</div>
I wrote a function to solve Euler #2 in Javascript for adding all the even Fibonacci numbers up to 4,000,000. However, when I run my function, the chrome dev tool keeps giving me zero as the answer. I am not sure why.
function DoEverything() {
oldnum = 0;
num = 1;
total = 0;
result = addFibNumbers(num, oldnum);
console.log(result);
}
function addFibNumbers(num, oldnum) {
while(num < 4000000) {
if (num % 2 == 0) {
newnum = num + oldnum;
total += newnum;
oldnum = num;
num = newnum;
}
return total;
}
}
DoEverything();
The reason its returning 0:
result = addFibNumbers(num, oldnum);//num=1,oldNum=0
//function
while(num < 4000000) { //num is 1, so it enters while
if (num % 2 == 0) {// 1 % 2 == 1, so skip this if
return total;// this ends the function, returning total=0 as nothing was changed
I guess you are looking to do this:
while(num < 4000000) {
newnum = num + oldnum;
if (newnum % 2 == 0 && newnum < 4000000) {
total += newnum;
}
oldnum = num;
num = newnum;
}
return total;
I would guess it is your while loop
Change this:
while(num < 4000000) {
if (num % 2 == 0) {
newnum = num + oldnum;
total += newnum;
oldnum = num;
num = newnum;
}
return total;
}
to this:
while(num < 4000000) {
if (num % 2 == 0) {
newnum = num + oldnum;
total += newnum;
oldnum = num;
num = newnum;
}
}
return total;
Your while loop is useless with a return in it and no if statement to control it's use.
In addition to modifying your while statement inside of addFibNumbers() like so:
function addFibNumbers(num, oldnum) {
while(num < 4000000) {
newnum = oldnum + num;
if (oldnum % 2 == 0) {
total += oldnum;
}
oldnum = num;
num = newnum;
}
return total;
}
you will also need to initialize the first two Fibonacci terms to 1 and 2:
oldnum = 1; and num = 2;