Changing for loop to while loop crashes javascript webpage? - javascript

New to JS. I'm trying to change my for loop to a while loop. It prints the factors of a number, but for some reason, the while loops causes the webpage to stop responding. Any help is appreciated.
var num, i = 1,
array = [];
num = parseInt(prompt("Please enter a number:"));
while (i < num) {
if (num % i == 0) {
array.push(i);
i++;
}
}
alert("The factors of " + num + " are: " + array + " and " + num);

Move the incrementation of i variable outside the if condition. Else - the while loop will be stuck when the num is not divisible by specified i.
For example - if num is 5 and i is 2, the loop will be stuck because the if condition is not fulfilled - that's why i won't be incremented - and then we will experience an infinite loop.
var num, i = 1, array = [];
num = parseInt(prompt("Please enter a number:"));
while (i < num) {
if (num % i == 0) {
array.push(i);
}
i++;
}
alert("The factors of " + num + " are: " + array + " and " + num);

You increment i only if the condition of the "if" block is true. If that condition evaluates to false, i can't be incremented, and therefore the loop never ends.
if (num % i == 0) { // <some value except 0> % 1 == 0 -> false
array.push(i);
i++;
}
so try:
while (i < num) {
if (num % i == 0) {
array.push(i);
}
i++; // now i can be incremented regardless of the condition in the "if" block.
}

Related

Only accept whole numbers, no decimals

I need my code to only accept whole numbers, no decimals and should prompt an error when a decimal gets entered. I don't want a new function , I'm hoping I can just add lines to my function but I don't know what I need to add.
function number_function() {
number = parseInt(prompt('Enter a positive integer:'));
if (number < 0) {
alert('Error! Factorial for negative number does not exist. But I will show you the positive number');
number = number * -1;
let n = 1;
for (i = 1; i <= number; i++) {
n *= i;
}
alert("The factorial of " + number + " is " + n + ".");
} else if (number === 0) {
alert("Please enter a number greater than 0");
} else {
let n = 1;
for (i = 1; i <= number; i++) {
n *= i;
}
alert("The factorial of " + number + " is " + n + ".");
}
}
number_function();
You can do this to check if the number has decimals
const val = 10.7 % 1;
if (val !== 0) {
console.log('has decimals');
} else {
console.log('has no decimal');
}
JavaScript provides the built-in function Number.isInteger(n)

why is outer variable not available in if conditional

function NumStuff(num) {
this.num = num;
this.multipleOfFour = function() {
//if multiple of 4
if (this.num % 4 === 0) {
console.log(this.num + " is a multiple of Four");
console.log("the structure of the given integer " +
this.num + " is ");
for (let i = 0; i < this.num; i++) {
if (4 * i === this.num) { //why is this.num outside of
//lexical scope
console.log(this.num + " = " + i + " x 4");
break;
}
}
//if not a multiple of 4
} else {
console.log(this.num + " isn't a multiple of 4 but here is the integer's structure:");
let remainder = this.num % 4;
let tempNum = this.num - remainder;
for (let i = 0; i < tempNum; i++) {
if (4 * i === tempNum) {
console.log(this.num + " = " + i + " x 4 + " + remainder);
break;
}
}
}
};
}
let num = prompt("Enter an integer:");
let n = new NumStuff(num);
n.multipleOfFour();
Say we enter 20 as our num. It passes through the multipleOfFour() and hits the first if conditional. This.num(20) % 4 is equal to 0 so it passes.Then we loop through i to find what number times 4 is equal to 20. This.num is in the scope of the for statement but not in the scope of the inner if conditional of the for statement. Why is that so?
It is in the scope. That's not the issue.
But this.num is a string (that's what prompt always returns) while 4 * i is a number. And 4 * i === this.num will always be false, regardless of what you enter when prompted.
Try this (here):
for (let i = 0; i < this.num; i++) {
console.log('x', 4 * i, this.num, 4 * i === this.num);
An easy fix is let num = parseInt(prompt("Enter an integer:"));.

checkPrime function returns incorrect values

numbers = [];
for (x = 1; x <= 1e4; x++) {
numbers.push(x)
}
//console.log(numbers)
function checkPrime(num) {
if (num == 1 || num == 0) {
return 'It is a separate case'
}
if (num == 2) {
return num + ' is prime'
}
for (var i = 2; i < num; i++) {
if (num in numbers) {
if (num % i === 0) return num + ' is not prime';
else {
return num + ' is prime';
}
return num !== 1;
} else {
return num + ' is not in range';
}
}
}
console.log(checkPrime(27));
Hi.
In the above code, I tried to create a function which returns information about whether a number is prime or not.
However, it fails in some cases. Like eg. in the case of 27 or 145, it returns the values are prime, which obviously is false. How can I amend this program to make it work?
Also, what is the smartest way of merging the case for number 2 and the rest prime numbers?
Thanks in advance and sorry if this is too basic, I could not find the right answer anywhere else.
You are putting the 'else' clause that states the number is prime before having finished to check all numbers until itself -1.
To be optimal, you don't need to loop until the number ( < num). Just until the square root of the number. (even better than looping until num/2) For example : 167 can be seen that is prime when the loop has reached 13. 13*13 = 169 > 167 so you can stop and safely afirm that 167 is prime.
For number 2 it is correct to have a sepparate case.
Below is the code for checking a single value if it is prime:
function checkPrime(num) {
if (num == 1 || num === 0) {
return 'It is a separate case'
}
if (num == 2) {
return num + ' is prime'
}
for (var i = 2; i < Math.sqrt(num); i++) {
if (num % i === 0) return num + ' is not prime';
}
return num + ' is prime';
}
alert(checkPrime(27));
I have rewritten the code to provide the right answer
numbers = [];
for (x = 1; x <= 1e4; x++) {
numbers.push(x)
}
//console.log(numbers)
function checkPrime(num) {
if (num == 1 || num == 0) {
return 'It is a separate case'
}
// check this condition outside the loop
if (!(num in numbers)) {
return num + ' is not in range';
}
if (num == 2) {
return num + ' is prime'
}
for (var i = 2; i < num; i++) {
if (num % i === 0) {
return num + ' is not prime';
}
}
return num + ' is prime';
}
console.log(checkPrime(27));
I've rewritten your code and made a couple of changes.
The reason you were having your problem is that you were returning in the for loop meaning all odd numbers would declare themselves as prime numbers.
I've fixed this but also I've I rearranged things a little, to be as efficient as possible it's good to bail as soon as possible so I do a couple of checks to bail initially I check if the number is in range, if not bail.
I've commented the code so it makes sense but if you don't understand why I've done something feel free to ask.
// make an array of all numbers between 0 and 10000
numbers = [];
for (x = 0; x <= 1e4; x++) {
numbers.push(x)
}
function checkPrime(num) {
// return if input number is not in numbers array
if (numbers.indexOf(num) == -1) return num + ' is not in range'
// return if number is 0 or 1
if (num <= 1) return 'It is a separate case'
// check all numbers between 2 and input number
// return if any number devides neatly
for (var i = 2; i < num; i++)
if (num % i === 0) return num + ' is not prime';
// if you get this far it's prime
return num + ' is prime';
}
console.log(checkPrime(27));
Personally, for the range, I wouldn't have an array of all the values but I've left this in just in case there was some other reasoning we don't know about.
EDIT:
As you've said the initial array is not important I've remade the code to work without it, I've not included comments this time (to save space) but that code does the same thing and is mostly unchanged.
function checkPrime(num) {
if (num < 0 || num > 1e4) return num + ' is not in range'
if (num <= 1) return 'It is a separate case'
for (var i = 2; i < num; i++)
if (num % i === 0) return num + ' is not prime';
return num + ' is prime';
}
console.log(checkPrime(27));
Anyway, I hope you find this helpful 🙂

Absence and presence of curly brace in "if" statement

var i = 0,
j = 8;
checkiandj: while (i < 4) {
console.log("i: " + i);
i += 1; // i=1;
checkj: while (j > 4) { //j=8
console.log("j: "+ j);
j -= 1; // 7
if ((j % 2) == 0)
continue checkj;
console.log(j + " is odd.");
}
console.log("i = " + i);
console.log("j = " + j);
}
How does this part of the code works?
if ((j % 2) == 0)
continue checkj;
console.log(j + " is odd.");
Is it like this?
if ((j % 2) == 0)
continue checkj;
else
console.log(j + " is odd.");
or like this?
if ((j % 2) == 0) {
continue checkj;
}
console.log(j + " is odd.");
And if I will read this statement(original one) at first look, I will understand it as: if Divide modulo 2 equal zero , do both continue checkj and console.log, not only continue. I know that what makes "continue" , but it`s hard to understand this action without curly braces. How can I understand better absence of curly braces?

javascript: summing even members of Fibonacci series

Yet Another (Project Euler) Fibonacci Question: Using (vanilla) javascript, I'm trying to sum the even numbers <= a given limit:
First, something is wrong with my 'if' statement, as some of the results (below) are wrong:
function fibonacciSum(limit) {
var limit = limit;
var series = [1,2];
var sum = 0;
var counter = 0;
for (var i=1; i<=33; i++) { // 33 is arbitrary, because I know this is more than enough
var prev1 = series[series.length-1];
var prev2 = series[series.length-2];
var newVal = prev1+prev2;
series.push(newVal);
counter ++;
console.log("series "+ counter + " is: " + series);
if (series[i] % 2 === 0 && series[i] <= limit) { // intending to sum only even values less than/equal to arbitrary limit
// sum = sum + series[i];
sum += series[i];
}
/*
var sum = series.reduce(function(a,b) {
/*
possible to filter here for even numbers? something like:
if (a %2 === 0)
*/
return a+b;
});
*/
console.log("SUM " + counter + ": " + sum);
} // for loop
} // fibonacci
fibonacciSum(4000000);
Results:
series 1 is: 1,2,3
SUM 1: 2
series 2 is: 1,2,3,5
SUM 2: 2
series 3 is: 1,2,3,5,8
SUM 3: 2 // looking for a '10' here
series 4 is: 1,2,3,5,8,13
SUM 4: 10
series 5 is: 1,2,3,5,8,13,21
SUM 5: 10
series 6 is: 1,2,3,5,8,13,21,34
SUM 6: 10 // looking for '44' here
Can someone please explain why neither of these working as intended?
if (series[i] % 2 === 0) { ...
... or
if (series[i] % 2 === 0 && series[i] <= limit) { ...
And secondly, as you can see I had also tried to use series.reduce(... but I can't figure how to sum only the even values; is that doable/cleaner?
Thank you,
Whiskey T.
No need for arrays. Use three variables for let's say previous, current and next numbers in fibonacci sequence.
We can also begin the sequence with 2 an 3 because there are no other even numbers that will affect the result.
We initialize the sum of even numbers with 2 because it's the current number and it's even. In a do...while we advance with the numbers in sequence and if the new numbers are even we add them to the sum. Stop when limit is reached.
function fibEvenSum(limit) {
var prev = 1,
current = 2,
next;
var sum = 2;
do {
next = prev + current;
prev = current;
current = next;
if (current >= limit)
break;
if (current % 2 == 0)
sum += current;
} while (true)
return sum;
}
This algorithm can be improved using properties of odd and even numbers:
odd + odd = even
even + even = even
even + odd = odd
This should work for you...
var fibonacciSum = function(limit) {
var nMinus2 = 1, nMinus1 = 2, evensFound = [2], sum = nMinus1;
while (sum <= limit){
var n = nMinus1 + nMinus2;
if (n % 2 == 0){
sum += n;
if (sum > limit){
break;
}
evensFound.push(n);
}
nMinus2 = nMinus1;
nMinus1 = n;
}
console.log("Evens found - " + evensFound);
return evensFound;
};
var evensFound1 = fibonacciSum(4),
evensFound2 = fibonacciSum(10),
evensFound3 = fibonacciSum(60),
evensFound4 = fibonacciSum(1000);
$(evenResults).append(evensFound1
+ "<br/>" + evensFound2
+ "<br/>" + evensFound3
+ "<br/>" + evensFound4);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="evenResults"></div>
A solution in the spirit of the one your attempted — with arrays — though as pointed out, they are not necessary.
var i = 0, sequence = [1, 2], total = 0;
while (sequence.slice(-1)[0] < 4000000) {
sequence.push(sequence.slice(-1)[0] + sequence.slice(-2)[0]);
}
for ( i; i <= sequence.length; i++ ) {
if ( sequence[i] % 2 === 0 ) {
total += sequence[i];
}
}

Categories

Resources