How to make an infinite for loop (for(;;)) not crash? - javascript

I'm new to JS, so most of my code hasn't worked. I've made a program to find out every prime number, but every time I use it, it crashes. Is there any way to make this code not crash upon running?
var i = 0;
for (;;) {
if (i % 2 === 0 || i % 3 === 0 || i % 5 === 0 || i % 7 === 0) {
i++;
}
else {
return i;
i++;
}
}

The correct approach is to use a single timer. Using setInterval, you can achieve what you want as follows:
window.onload = function start() {
primes();
}
function primes() {
var i = 0;
window.setInterval(function () {
if (i % 2 === 0 || i % 3 === 0 || i % 5 === 0 || i % 7 === 0) {
i++;
} else {
console.log(i);
i++;
}
}, 1000); // repeat forever, new value every 1 second
}
This will print the values to the console once a match is found (It does a check every second). But you can adjust this on the second parameter of the setInterval function.
If you want the results on the actual page, you can replace the console.log() with document.createTextNode().
Also, i have not checked this or know if the algorithm is right. Just adapted from your code.

List of fixes:
You manually update i and use a blank for loop instead of using the for loop normally, but having the middle condition always return true (a while loop could be used here also, but would still require manually updating i) as you don't plan on stopping. However, you can actually just put the whole thing in a timer instead of a loop, like #Leonel Atencio did.
You use return outside of a function, and if you did put this code inside of a function, it would just return the first prime number every time, so it would always return 1.
The formula is incorrect, only checking for some examples of primes; As #Alexandru-Ionut Mihai said, 121 would be considered prime, even though it is 11x11.
Fixed:
var primes = [];
var i = 1; //Start at 2; since "i" is incremented at the start of the function, this won't start it at 1, which would cause problems (the array would only have 1 in it, since all other whole numebrs are divisible by one)
setInterval(primeFunc,100);
function primeFunc(){
i++; //Increment current number
isPrime=true; //Assume prime
for(var j=0;j<primes.length;j++){ //Rule out non-primes with the power of modulo
if(i%primes[j]==0) { //If the current number can be divided (is divisible) by any previous prime...
//...then it's not a prime, so cancel any further chacks and move on
isPrime=false;
break;
}
}
if(isPrime){
//The current number is not divisible by any other primes, so it is itself a prime; if it was divisible, isPrime would be set to false by our loop above
primes.push(i);
output.innerHTML=primes;
}
}
<span id="output"></span>

Related

How to Iterate the next 10 in a while loop

I am trying to iterate a count of every 10 in a while loop. The code below counts 200 10 times and then stops, the reason it stops is that I need to store the first 10 in a spreadsheet, but that is another problem to solve, right now, I am not sure how to go about moving onto the next 10 counts taken from the first 10 count in the while loop below.
while (go) {
data = getRecordsByPage(i,200,token,module);
if (Number(data.info.count) < 200) {
go = false;
};
if (i == 10) {
go = false;
while(go = false)
{
Utilities.sleep(10000)
}
if(Utilities.sleep == 10000)
{
go = true;
}
}
rows = Number(rows) + Number(data.info.count);
i++;
Logger.log(rows)
}
Also, please let me know if having a nested while loop in this is loop a good way to restart the loop again with the timer before it restarts.
How about using modulo?
replace if (i == 10) { by if (i%10 == 0) {
This way, it will enter in your if statement every multiple of 10

while loop to print out only odd numbers in javascript

let number = 0;
while (true) {
if (number%2 === 0) continue;
console.log(number);
number ++;
}
I wanted to infinite loop to print out only odd numbers. But this doesn't seem to work. What am I doing wrong?
Let's have a brief understanding of the code execution.
When the following code is executed...:
let number = 0;
while (true) {
if (number%2 === 0) continue;
console.log(number);
number ++;
}
...the following happens:
The first line allocates memory for a variable named number and stores a value of 0.
The while loop starts, and it checks whether the condition is true, and yes it is, and always will be, as the condition is simply true.
Then, it checks whether the number mod 2 returns 0, and definitely, it does, since 0รท2 is 0 and the remainder is 0, so the condition inside the if statement is true, and therefore it executes the code correspondingly. When it sees continue, it jumps back to step 2 and checks the while loop condition, then comes back here, then goes back to step 2, then again comes back here and this never ends(ends when you stop the code execution or close your browser obviously).
Simply put, it never goes forward to the console.log and the number++ line. This is why your code isn't working.
The code from others work because the control actually moves forward in the code and never actually becomes stuck in the above loop.
Try this code
let number = 0;
while (true) {
if (number % 2 != 0)
console.log(number);
number ++;
}
The code you're using will not work because you defined number=0 and then you're checking the condition if(number%2==0) continue; so this condition will always return true because the number is defined 0 and the number++ will never increase.
let number = 0;
while (true){
if (++number % 2 == 1){
console.log(number);
}
}
no need a continue statement, just check the remainder is 1 the print the value in the loop.
you can further shorten the if condition as if (++number % 2)
You should increment the number when it is even also, to check the next number and so on:
let number = 0;
while (true) {
if (number%2 === 0){
number++;
continue;
}
console.log(number);
number ++;
}
Whatever number is, increment it first. Otherwise, when it is even, it never reaches to number++ any more.
let number = 0;
while (true) {
number ++;
if (number%2 === 0) continue;
console.log(number);
}

JavaScript loop using set amount of steps while skipping specific step

I am trying to create a loop that allows you to go up in increments of one each time using "x" amount of steps while skipping a specific step. example 1 would be you have 2 actions and need to skip step 2. so you would go from 0 to 1 and then 1 to 3. example 2 would be you have 3 actions and need to skip step 3 so you could either go from 0 to 1, wait 1 round, then go from 1 to 4 since you would be skipping up two. or you could wait at 0 then skip to 2 and then skip to 5.
i know I am close using a while loop with continue but it doesn't quite work like expected.
function maxStep(n, k) {
let step = n
let bad = k
let total = 0
while (total <= step) {
total += 1
if (total === bad) {
continue;
}
total += 1
return total
}
}
Hello and welcome #jaronow!
First, continue skips you to the next iteration of the while. So what you've written here...
if (total === bad) {
continue;
}
total += 1
...actually means, "If this is a bad number of steps, then skip adding 1." But you mean the opposite, don't you?
if (total === bad) {
total += 1
}
This now says, "If this is a bad number of steps, add another 1." There, so now we have
function maxStep(n, k) {
let step = n
let bad = k
let total = 0
while (total <= step) {
total += 1
if (total === bad) {
total += 1 // Put this here instead of continue.
}
return total
}
}
Now, where you put this is odd:
return total
This actually exits the entire function the first time it's encountered. Surely you mean to calculate total by running through your loop as many times as needed, then return the result at the end, like this:
function maxStep(n, k) {
let step = n
let bad = k
let total = 0
while (total <= step) {
total += 1
if (total === bad) {
total += 1
}
}
return total // Moved this out.
}
Finally, there's two subtle issues (noticed the second one later). First, if you take that "extra step" because you've encountered a bad step, you need to increase step as well, since it's the maximum number of steps you plan to take. But also, once you reach that number of steps, you don't want to enter the loop again and add another to total, so you need to use < instead of <=. (You'll find it a common pattern in programming that when you intend to do things N times, you write your loops saying < N, not <= N.)
function maxStep(n, k) {
let step = n
let bad = k
let total = 0
while (total < step) {
total += 1
if (total === bad) {
total += 1
step += 1 // Add this.
}
}
return total
}
Otherwise, your total will always end up at the original number of steps.
There are other shorter, possibly more clever ways of solving this problem, but I'm aiming to teach by sticking to your formulation.
Not something you have to care about, but in case you want to see, a seasoned programmer may "refactor" your code this way:
function getStepsTaken(desiredStepsToTake, badNumberOfSteps) {
let stepsToTake = desiredStepsToTake
// let bad = k (don't need this line)
let stepsTaken = 0
while (stepsTaken < stepsToTake) {
stepsTaken += 1
if (stepsTaken === badNumberOfSteps) {
stepsTaken += 1
stepsToTake += 1
}
}
return stepsTaken
}
You may find it ugly, and indeed it's much more verbose, but it's always better to make things very clear, even if just for yourself and you rename the variables later.
Solid attempt though, keep it up.

How to make if statement true only once?

How do I make an if statement run only once. I am making a game in javascript and once the users score is 5 I want to add a new enemy into the array. The problem I am having is once the if statement is true it keeps adding new enemies over and over until the whole screen is covered with enemies. I want it to add only 1 new enemy when score is 5 then another when score is 10 and so on. I cannot think of a way to accomplish this. Thank You.
Sketch.js
var score = 0;
//3 three enemies once game starts
function StartingEnemies() {
for (var i = 0; i < 2; i++) {
enemies[i] = new BasicEnemy();
}
}
//add new enemies into the array
function spawnNewEnemies() {
enemies.push(new BasicEnemy());
}
if (score == 5) {
spawnNewEnemies();
}
var addNew=true;
if (score == 5 && addNew) {
spawnNewEnemies();
addNew=false;
}
If you are running the code inside of a function, make sure that addNew is declared somewhere that it will persist between calls.
You need a simple latch. Try adding a boolean variable called isEnemyAddedAtFive and set it to false as it's default value.
var isEnemyAddedAtFive = false;
Then at your check point test this value and if not latched, act and latch:
if( score == 5 && !isEnemyAddedAtFive ) {
addEnemy();
isEnemyAddedAtFive = true;
}
Good Luck!
if ( score != 0 && score % 5 == 0) {
spawnNewEnemies();
}
Try this one.
This is a little more complex than you are currently coding. There are a few ways you could interpret this. Firm your requirements.
Do you want to only add an enemy if the score is divisible by 5... Meaning only when the score ends in 0 or 5 (5, 10, 15, 20, etc):
If (score % 5 == 0) {
enemies.push(new BasicEnemy());
}
Otherwise you may need to track a total score and a level/segmented score representing the score since the program last took action on the game.
// Initialization
var totalScore = 0;
Var currents core = 0;
// Game event loop
while (player.lifeState > 0) {
// Check current score is 5 or more on every iteration of the game event loop
if (currentScore >= 5) {
// Handle score
spawnNewEnemies();
// Update scoring
totalScore += currentScore;
// Reset currentScore (or not if you want to do more stuff in the level before resetting but this may change the above logic)
currentScore = 0;
}
Your logic will get more complex as you as more features. The best first step is to define clear requirements before coding as one retirement may influence how you implement another
//post this snippet at some top level of your code.
var onceMap = {};
function once(key) {
if (onceMap[key]) {
return false;
} else {
onceMap[key] = true;
return true;
}
}
var score = 10;
//do this in your task function
function task() {
if (score >= 5 && once("score5")) {
console.log("score 5 action");
}
if (score >= 10 && once("score10")) {
console.log("score 10 action");
}
}
task();
task();
task();
What comes first to mind after seeing your code is that:
It should be
for (var i = 0; i < 3; i++)
for 3 enemies
You are calling your code (i.e .js file multiple times). This means that score resets to 0 each time it is called and score==5 condition occurs multiple times.
Solution:
Change your logic such that the .js file is called only once and store the score for the entire duration of the game.
Hope this helps
!( score != 0 && score % 5 == 0) || spawnNewEnemies()
//how it functions
!true || run()
I'll have to admit this is a bit abstract. But what this does is if the score is true, it forces into false and runs spawnNewEnemies. If the score isn't true. It forces into true and don't run the false condition.
However id suggest a function edit:
var spawnNewEnemies =scored=> !(scored !=0 && scored%5===0) || enemies.push(new BasicEnemy());
spawnNewEnemies(score);
SpawnNewEnemies now takes a score parameter. But also is an arrow function that can be used for quick one-liners. Since score is a dependency, itll run on that condition. If the base score is 0 and also divisible by 5, the condition returns true, but the "bang" (!) operator forces it into false, and executes the new enemies. If the score isn't divisible by five, itll return false but the bang flips it and will not return the OR false arguement.

Why does console.log() keep on going in this loop?

I defined a variable 'i' to be equal to 2, and then say: if 'i' is between 0 and 2, let the function 'animate' run. However, if I open up the console in JSFiddle (option-command-I), the console.log() continues decreasing by 1 below 0! Am I using the conditional in the if statement improperly?
var interval = window.setInterval(animate, 500);
var i = 2;
if (0 < i < 2) {
function animate() {
alert('run');
i--;
console.log(i);
}
}
JSFiddle: http://jsfiddle.net/lpsternotes/RuLHn/
There are two problems here.
Firstly, there is this: 0<i<2. This will always evaluate to true.
Why? What you hoped it meant was "i is between 0 and 2" (which could be written as 0<i && i<2). But to a JS compiler, it is just two instances of the < operator. First, 0<i is evaluated, resulting in either true or false; then, that result is compared against <2 - so we have either true<2 or false<2. In order to answer that question, JS must "cast" the true or false to an integer. It treats false as 0, and true as 1; since these are both <2, the final result is always true.
Secondly, there is the position of your if statement, which is checked only once:
if (0 < i < 2) {
function animate() {
If you read through the code, you will see that there is no way of getting back to the line above this if statement, since the only repeating part of the code is the interval repeatedly running the animate function. To run each time the function runs, the if needs to be inside the function, not the other way around.
You need to clear interval once you satisfy the condition and move the if condition (note that 0 < i < 2 needs to be split into 2 conditions joined with && but here you can just do) with modification inside the function.
var interval = window.setInterval(animate, 500);
var i = 2;
function animate() {
if (i > 0) {
console.log('run');
i--;
console.log(i);
}
else{
window.clearInterval(interval);
}
}
Why don't you put if statement inside your animate function?
var i = 2;
function animate () {
if (i> 0 && i<2) {
alert('run');
i--;
console.log(i);
}
}
Edit:
1) you might want to use i>0 && i<2 rather than 0
2) Not sure if you do need to clear the interval after the condition is met. Would be better if you could elaborate a bit more about your requirements.

Categories

Resources