How can I convert these 'if' statements to an algorithm - javascript

I'm trying to convert these 'if' statements to an algorithm, so that I can have many more stages instead of being limited to 10. How would I go about converting it? I just can't wrap my head around the logic!
function getStage(km) {
if (km > 2 && km < 4){
return 1;
}
else if (km > 4 && km < 6){
return 2;
}
else if (km > 6 && km < 8){
return 3;
}
else if (km > 8 && km < 10){
return 4;
}
else if (km > 10 && km < 12){
return 5;
}
else if (km > 12 && km < 14){
return 6;
}
else if (km > 14 && km < 16){
return 7;
}
else if (km > 16 && km < 18){
return 8;
}
else if (km > 18 && km < 20){
return 9;
}
else if (km > 20 && km < 22){
return 10;
}
}
I have tried this:
function getStage(km) {
var tempStage = 0;
for (var i = 0; i < stages; i++) {
var stage = i + 1;
var tempKm = stage * 2;
var nextKm = stage + 2;
if (km > tempKm && km < nextKm) {
tempStage = stage;
}
}
return tempStage;
}
Perhaps I shouldn't be using a for loop? Is there a better way of doing this?

Maybe you are looking for Math.floor
function getStage(km) {
return Math.floor(km / 2)
}
console.log(getStage(2));
// 1
console.log(getStage(10));
// 5
console.log(getStage(11));
// 5

You can just use math to do this. No loops or conditionals necessary.
Notice that your input intervals increase in "steps" of 2, and your outputs increase in "steps" of 1. This makes me think maybe we should divide km by 2.
Since we always want an integer answer, we can use the Math.floor function.
Some examples:
Math.floor(3/2) = 1
Math.floor(4.1/2) = 2
etc.
Depending on what you want to return for edge cases (what if km = 2 or km = 4, or any multiple of 2?) we might be done here. If you wish to return 1 when k=4, 2 when k=6, etc., you'll need to do a little more work.
*** In general: *** if you are working with numbers and you find yourself writing a lot of cases, you can usually use some combination of simple mathematical operators to calculate the result. For problems like these, try thinking about your input/output pairs, and what the relationship is between them.

You could take the floored value of km divided by two plus one.
10 is the upper limit.
function getStage(km) {
return Math.min((km >> 1) + 1, 10);
}
console.log(getStage(2.1)); // 2
console.log(getStage(3)); // 2
console.log(getStage(4)); // 4

Try something like this. This is general solution which applies not only to 2*n series.
const stages = [2, 4, 6, 8, 10, 13, 15, 16, 20]; //should be ordered. Else sort it first.
const getStage = km => stages.indexOf(stages.find(i => km < i));
console.log(getStage(5)); //2
console.log(getStage(1.5)); //0
console.log(getStage(8.1)); //4
console.log(getStage(15)); //7
console.log(getStage(22)); //-1 out of index

Related

functions result is NaN

I am really new in coding therefore I am coding currently a Taximeter. Unfortunately is the result of my code when executing NaN in the console. I tried some ways to rectify my problem but those attempts did not work. I think that some variables are not in the right scope but I do not know how to fix that.
function Taximeter() {
const y = 3.9;
const km = prompt("How far is your target");
if (km <= 7) {
var routePrice = 2.3;
} else if (km > 7) {
let routePrice = 1.65;
var subtractedLength = (km -= 7);
var partialExpenses = (subtractedLength *= routePrice);
var tosevenExpenses = 7 * 2.3;
var combinedExpenses = (tosevenExpenses += partialExpenses);
}
const persons = prompt("How much persons are driving with you?");
if (persons > 8) {
console.log("Only 8 persons can drive with you.");
} else if (8 >= persons >= 5) {
var personsExpenses = 5;
} else if (0 >= persons >= 4) {
personExpenses = 0;
}
if (km <= 7) {
var wholeExpenses = y + km * routePrice + personsExpenses;
} else {
var wholeExpenses = combinedExpenses + y + personsExpenses;
}
console.log(wholeExpenses);
}
It would be helpful to know where exactly NaN is coming up and whether or not you are seeing NaN as the result of an Exception (if an error message was logged to the console) or if NaN is coming up as a result of your own console.log() statements. Part of the issue could be that the function prompt() returns a String, meaning that your variable km is going to be a String and not a Number. Use this line of code instead and it might fix your problem:
const km = parseInt(prompt("How far is your target"));
EDIT:
In response to your comment, there are a couple other issues I see here. There is the issue with your first if and else if clauses where the indentation is a little off. This, as far as I can tell, should not actually affect your code, but it does make it harder to read. Here is how it should look:
if (km <= 7) {
var routePrice = 2.3;
} else if (km > 7) {
let routePrice = 1.65
var subtractedLength = km -= 7;
var partialExpenses = subtractedLength *= routePrice ;
var tosevenExpenses = 7 *2.3;
var combinedExpenses = tosevenExpenses += partialExpenses;
};
Second, in those same if and else if clauses, you use the -=, *=, and += operators when they are unnecessary and may cause errors. I've never seen them used the way that you have before, so I don't know if they actually cause errors, but I would edit those clauses one more time for readability at least:
if (km <= 7) {
var routePrice = 2.3;
} else if (km > 7) {
let routePrice = 1.65
var subtractedLength = km - 7;
var partialExpenses = subtractedLength * routePrice ;
var tosevenExpenses = 7 *2.3;
var combinedExpenses = tosevenExpenses + partialExpenses;
};
Like with km I would also edit your persons declaration to turn that variable into a Number so that the logic operators that you use on it later work properly:
const persons = parseInt(prompt("How much persons are driving with you?"));
Another thing, like a commenter earlier pointed out, 8 >= persons >= 5 will not work the way you think it will - just edit those if and else if clauses like so to fix that error:
if (persons > 8) {
console.log("Only 8 persons can drive with you.");
} else if(persons >= 5 && persons <= 8) {
var personsExpenses = 5;
} else if (persons <= 4 && persons >= 0) {
personExpenses = 0;
};
Finally, your variable declaration of personsExpenses is such that the variable will only be declared if that first else if clause resolves. You need personsExpenses to be declared no matter what, so I would declare it before and outside of any of those conditional clauses:
var personsExpenses
if (persons > 8) {
console.log("Only 8 persons can drive with you.");
} else if(persons >= 5 && persons <= 8) {
personsExpenses = 5;
} else if (persons <= 4 && persons >= 0) {
personExpenses = 0;
};
That's everything that I noticed, so good luck!

Grading Students in JS with recursion - Range Error

I was trying to work on this hackerrank problem.
Every student receives a grade in the inclusive range from
0-100 to .
Any less than 38 is a failing grade.
Sam is a professor at the university and likes to round each student's according to these rules:
If the difference between grade the and the next multiple of
5 is less than 3, round up to the next multiple of 5. If the value of grade is less than 38, no rounding occurs as the
result will still be a failing grade.
Given the initial value of for each of Sam's students, write code to
automate the rounding process.
My code is:
function gradingStudents(grades) {
const roundup = y => y + 1;
{
if ( grades < 38 || grades % 5 === 0) return grades;
else if ( grades % 5 < 4 && grades % 5 !== 0) return roundup(grades);
}
{
if (roundup % 5 === 0) return roundup;
else { gradingStudents(roundup + 1) }
}
}
gradingStudents(38) // -> 39
I tried to use Math.ceil(grades) inside the variable roundup but output didnt change. So, when you invoke the function with a number that is not before a multiple of 5 (e.g. 43) it returns the proceeding number. However, if it is the number before a multiple of 5 it gives a range error. "maximum call stack size reached."
As far as I got, the code doesnt proceed to the second part. Even if it did, I am not sure if it would fetch the current value of the function roundup when dealing with if statements in the second block.
What do I dont get in here?
Also, this is actually meant for an array output but since I am a beginner I am pretty much okay with this one for the start as well :D .
Javascript solution:
function gradingStudents(grades) {
return grades.map((grade) => {
if (grade > 37) {
const offset = 5 - (grade % 5);
if (offset < 3) {
grade += offset;
}
}
return grade;
});
}
Try this:
function gradingStudents(grades) { //input: 43
var finalGrade;
if(grade < 38)
return grades;
else{
var gradeDif = grades % 5; //3
if(gradeDif > 3){
return grades;
}
else {
return grades + (5 - gradeDif); //Output: 45
}
}
}
One solution calculates the next multiple of 5 no bigger than the grade and uses that value to test whether or not to round up (next5 - grade < 3).
We write a simple function to round an individual grade and then for a list of grades use .map with that function.
const roundGrade = (grade) => {
const next5 = 5 * Math.ceil (grade / 5)
return (grade < 38) ? grade : (next5 - grade < 3) ? next5 : grade
}
const gradingStudents = (grades) =>
grades .map (roundGrade)
console .log (gradingStudents ([73, 67, 38, 33]))
Note that, like most solutions to this problem, no recursion is needed.
1-Use the Array.prototypt.map according to the question logic.
const gradingStudents = (grades) => grades
.map(n => (n >= 38 && n % 5 >= 3)?(n + ( 5 - ( n % 5 ) )):n )
let result = gradingStudents([0,25,38,56,89,77,78,57,58])
console.log(result)
My solution is this
function gradingStudents(grades) {
grades.map((grade,i)=>{
if(grade >= 38){
let fg = (grade/5).toString().split('.');
if(fg[1]>5){
grades[i]=((parseInt(fg[0],10)+1) * 5);
};
}
});
return grades;
}
console.log(gradingStudents([73,67,38,33]));
my solution:
function gradingStudents(grades) {
return grades.map(function(grade) {
return (grade >= 38 && grade % 5 >= 3) ? grade + 5 - (grade % 5) : grade;
});
}

Optimizing and finding edge cases that I might have missed - 2 coding interview questions

Background - I took an online coding test and was presented with questions similar to this, I did rather poorly on it compared to the hidden grading criteria and I was hoping to get another pair of eyes to look at it and maybe help point out some of my mistakes.
Practice Test questions -
Task: Given an integer inject the number 5 into it to make the largest possible integer
Conditions: (-80000...80000) range needed to handle
Expected input: int
Expected output: int
Testcase: -999 -> -5999
80 -> 850
var lrgInt = function(num) {
var stringInt = num.toString();
for (let i = 0; i < stringInt.length; i++) {
if (stringInt.charAt(i) === "-") {
return parseInt([stringInt.slice(0, 1), '5', stringInt.slice(1)].join(''));
}else if (stringInt.charAt(i) < 5) {
return parseInt([stringInt.slice(0, i), '5', stringInt.slice(i)].join(''));
}
}
return parseInt([stringInt.slice(0, stringInt.length), '5', stringInt.slice(stringInt.length)].join(''));
};
Task: Determine the number of operations done on a number following the conditions to reduce it to 0.
Conditions:
- If the number is odd, subtract 1
- If the number is even, divide by 2
Expected input: int
Expected output: int
var operations = 0;
var numberOfSteps = function(num) {
if (num === 0){
return operations;
}else if (num % 2 == 0) {
operations++;
return numberOfSteps(num/2);
} else {
operations++;
return numberOfSteps(num-1);
}
};
For the second question, you could add one plus the result of recursion with the adjusted number without having a global counter.
function numberOfSteps(number) {
if (!number) return 0;
if (number % 2) return 1 + numberOfSteps(number - 1);
return 1 + numberOfSteps(number / 2);
}
console.log(numberOfSteps(5)); // 5 4 2 1 0
For the first question, we make the observation that if the number is positive, we want to inject the 5 before the first digit less than 5, but if it's negative then we want to inject it before the first digit greater than 5. For the second problem, we can just use a simple while loop.
function largestNum(num) {
if (num == 0) {
// this edge case is weird but I'm assuming this is what they want
return 50;
}
var negative = num < 0;
var numAsStr = Math.abs(num).toString();
var inj = -1;
for (var i = 0; i < numAsStr.length; i++) {
var cur = parseInt(numAsStr[i], 10);
if ((!negative && cur < 5) || (negative && cur > 5)) {
// we found a place to inject, break
inj = i;
break;
}
}
if (inj == -1) {
// didn't inject anywhere so inject at the end
inj = numAsStr.length;
}
return (
(negative ? -1 : 1) *
parseInt(numAsStr.substr(0, inj) + "5" + numAsStr.substr(inj))
);
}
function numSteps(num) {
var steps = 0;
while (num != 0) {
if (num % 2) {
// it's odd
num--;
} else {
num /= 2;
}
steps++;
}
return steps;
}

Greater than X but less than Y javascript

I am new here, but i'm simply trying to figure out why this javascript is not working in my math program.
For the last two IF statements, i'm comparing numbers. Greater than X but less than Y...
(function(){
if(fieldname4-fieldname3 < 30) return (1));
if ((fieldname4-fieldname3 > 31) && (fieldname4-fieldname3 < 60)) return
(2);
if ((fieldname4-fieldname3 > 60) && (fieldname4-fieldname3 < 90)) return
(3);
})();
Thanks for any help you can give me.
EDIT: I'm going to post the full script when i'm back to my compuer. Sorry for being so vague. It wasn't intentional. I'm still learning.
You can try to write a better code. For example:
(function(){
if(fieldname4-fieldname3 < 30){
return 1; //returns 1 for every number smaller then 30
}
if(fieldname4-fieldname3 >= 30 && fieldname4-fieldname3 <= 60){
return 2; // returns 2 for every number smaller then 60(includes 60) and greater then 30(includes 30)
}
if(fieldname4-fieldname3 > 60 && fieldname4-fieldname3 < 90){
return 3; // returns 3 for number smaller then 90 and greater then 60
}
})();
I hope that this will help you
Just shooting at it in the dark without seeing the script but how about this??
function test (fieldname4, fieldname3) {
var fieldResult = fieldname4 - fieldname3;
if(fieldResult < 30) {
return 1;
} else if ((fieldResult > 31) && (fieldResult < 60)) {
return 2;
} else if ((fieldResult > 60) && (fieldResult < 90)) {
return 3;
}
};

Looking for a formula to check if a number is the product of a number 2 or greater times a number 3 or greater

I am looking for a formula to use in an IF statement to determine if a given number is the product of a number 2 or greater multiplied by a number 3 or greater.
For instance, 6 is the smallest number that meets the requirement (2 x 3). 7 doesn't, 8 does (2 x 4), 9 does (3 x 3), 10 does (2 x 5), 11 doesn't, 12 does (2 x 6), etc.
Any ideas?
Thanks!
Sounds like you're doing primality testing. You should check out that Wikipedia article - they've got several algorithms to pick from.
Hope that helps!
To check is a number is a multiple of 2, use the mod (%) operator.
so
if((x%2 == 0) || (x%3 == 0) )
//x is a multiple of 2 or 3
This finds the smallest factor for n that is at least 2, then finds the smallest factor that is greater than that and greater than 3, and once it does, it returns true.
function myFunction(n) {
if (isNaN(n) || !isFinite(n) || n%1 || n<6) return false;
var m = Math.sqrt(n);
for (var i = 2; i <= m; i++) {
if (n % i == 0) {
var divided = n / i;
for (var j = (i > 2) ? i : 3; i <= n / i; i++) {
if (divided % j == 0) {
return true;
}
}
}
}
return false;
}
x needs to be a multiple of two factors...(y, z)
flag = false; (boolean. set when found);
for(var y = 2; y < x; y++){
for(var z = 3; z <= (x/y); z++){
if(y*z == x){
flag = true;
}
}
}
if(flag){
now we know that x meets the requirements
}

Categories

Resources