Evaluating Terminating Condition - javascript

I am learning javascript to enhance some of my daily work, and so I am learning the basics.
I am still pretty green with the syntax, but am picking up on the language pretty quickly.
What I am trying to understand is how i can create a terminating condition that is evaluating a function.
I know the coding is wrong here, which is what I am trying to fix - I attempted a bunch of different things, but I am having trouble evaluating the loop based on my product.
I tried using return to store the value each iteration, but every attempt resulted in the script flat out failing.
What I want the script to do is to stop the loop when my product reaches <=100.
The problem is, my research suggests that the loop criteria can ONLY be referencing the variable, i.
I'm stuck in terms of how to look at the resulting product as the terminating condition.
var one = 5;
var two = 10;
var end = 100;
function mult (one, two) {
var product = one * two;
document.writeln(product + "<br>");
}
for (var i = 1; i <= end; i++)
mult(i, two);

If you want your loop to terminate when the product is <= 100, use an if statement to decide whether you want to write a line.
I've changed some variable names to make it easier to understand.
/*var one = 5;*/ /*This is never being used*/
var ten = 10;
var end = 100;
function mult (a, b){
var product = a * b;
if (product <= 100){
document.writeln(product + "<br>");
}
}
for (var i = 1; i <= end; i++){
mult(i, ten);
}

"the loop criteria can ONLY be referencing the variable, i." that's false!
You can define multiple conditions in a for loop.
To access the 'product' variable after loop execution you can declare it in the outer scope of the mult() function (or you can rewrite the mult() function to returns the product variable).
Like this:
var two = 10;
var end = 100;
var someNumberGtThan100 = 100000;
var lastProduct = 0;
var product = 0;
function mult (one, two) {
lastProduct = product;
product = one * two;
document.writeln(product + "<br>");
}
for (var i = 1; i <= someNumberGtThan100 && product <= 100; i++) {
mult(i, two);
}
console.log(lastProduct); // 100
By using this condition you have to store the previous value in an auxiliary variable, because when 'product' reach the value of 100 the loop condition is still true, so the loop will be executed one time more.

Related

What's difference between printing code in and out of curly braces?

What's difference between returning out of curly-braces and in of it within for loops?
I have this code making 'factorial' in for loops code quiz of Udacity and it is marked as 'right answer' only if 'console.log(solution) is out of for loop braces. Why can I put it inside for loop? Can't really understand why is that.
var solution = 12;
for (var i = 1; i < 12; i++) {
solution = solution * i;
console.log(solution); /* Why inside of the loop like this is
wrong? */
}
var solution = 12;
for (var i = 1; i < 12; i++) {
solution = solution * i; // 12 = 1 * 2 * 3 * .... 12
}
console.log(solution); /* only it works when it's out of the loop
like this one but why???? */
The difference is that inside the loop you are outputting the contents, or the current state of solution every time the loop repeats (in this case 11 times), when it's outside the loop body, you are only outputting the final state of the variable, or just 1 time.

Coin Flip and Counter Javascript

So I'm trying to make this coin flip but it keeps flipping forever... when I want it to stop after 10 times. I also need a counter variable that tells me how many times it is flipped.
var coin = randomNumber (0,1);
write (coin);
while (coin < 10) {
coin = randomNumber (0,1);
write (coin);
}
The easiest way is to just use a for loop.
for (var i = 0; i < 10; i++) {
var coin = randomNumber (0, 1);
write (coin);
}
See this for more information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration
If you want to stick to the while loop:
var timesFlipped = 0;
while (timesFlipped < 10) {
var coin = randomNumber (0, 1);
write (coin);
timesFlipped = timesFlipped + 1; // alternatively: timesFlipped++;
}
You haven't shown us your randomNumber function, but it's likely that it only produces numbers that are less than 10. Since your while loop says to keep going as long as coin is less than 10, the loop goes forever.
while loops are notorious for resulting in infinite loops. I personally never use them. Since you know how many times you need to loop, a counting loop is the correct choice.
Here's what you need:
// Write the function that gets random number and report the results a certain number of times:
function coinToss(numTimes) {
// Instead of a while loop, use a counting loop that will
// have a definite end point
for(var i = 0; i < numTimes; i++){
// Get a random number from 0 to 1
var coin = Math.floor(Math.random() * 10);
// Test to see if it is even or odd by checking to see if
// it is divisible by 2 with no remainder.
var even = (coin % 2 === 0);
// Report the results
console.log("The coin was " + (even ? "heads " : " tails"));
}
}
// Now, call the function and tell it how many times to loop
coinToss(10);

JS crashes sometimes with Timer scramble

My Javascript timer is for people with a rubiks cube with generates a scramble (nevermind all this, but just to tell you I'm generating after each solve a new scramble will be generated) and my scrambles do actually have a while (true) statement. So that does crash my script, but it 95/100 times stops just before the script crashes but I don't wanna have any times.
Let me explain a bit more detailed about the problem.
Problem: javascript crashes because my script takes too long to generate a scramble.
Below you have 3 functions I use.
This function generates a scramble with the Fisher-Yates shuffle.
Timer.prototype.generateScramble = function(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
};
This function validates the input e.g. I receive an array as the following:
Here I only have to check the first character. That's why I use the seconds [ ] notation. I don't want people get an F with an F2 e.g.
var scr = ["F","R","U","B","L","D","F2","R2","U2","B2","L2","D2","F'","R'","U'","B'","L'","D'"]
Timer.prototype.validateScramble2 = function(array) {
var last = array.length-1;
for (var i = 0; i < array.length-1; i++) {
if (array[i][0] == array[i+1][0]) {
return false;
}
}
for (var i = 0; i < array.length-2; i++) {
if (array[i][0] == array[i+2][0]) {
return false;
}
}
if (array[0][0] == [last][0]) {
return false;
}
return true;
};
The above functions are just waiting to be called. Well in the function below I use them.
Timer.prototype.updateScramble2 = function(scrambleArr, len, type) {
var self = this;
var scramble = '', j, updatedArr = [];
while (updatedArr.length < len) {
j = (Math.floor(Math.random() * scrambleArr.length));
updatedArr.push(scrambleArr[j]);
}
while (!self.validateScramble2(updatedArr)) {
updatedArr = self.generateScramble(updatedArr);
}
for (var i = 0; i < updatedArr.length; i++) {
scramble += updatedArr[i] + ' ';
}
scrambleDiv.innerHTML = scramble;
};
I assume you guys understand it but let me explain it briefly.
The first while-loop adds a random value from the given array(scrambleArr) into a new array called updatedArr.
The next while-loop calls the validateScramble2() function if there isn't in an array F next to an F2.
The for-loop adds them into a new variable added with a whitespace and then later we show the scramble in the div: scrambleDiv.innerHTML = scramble;
What do I need know after all this information?
Well I wanna know why my updateScramble2() functions lets my browser crash every time and what I do wrong and how I should do it.
I'm not entirely sure I understand the question, but from the way your code looks, I think you have an infinite loop going on. It appears as if validateScramble2 always returns false which causes your second loop in updateScramble2 to perpetually run.
I suggest you insert a breakpoint in your code and inspect the values. You could also insert debugger; statements in your code, works the same way. Open dev tools prior to doing these.
A suggestion is instead of using loops, use a timer. This breaks up your loop into asynchronous iterations rather than synchronous. This allows the browser breathing space for other operations. Here's an example of a forEachAsync:
function forEachAsync(array, callback){
var i = 0;
var timer = setInterval(function(){
callback.call(null, array[i]);
if(++i >= array.length) clearInterval(timer);
}, 0);
}
forEachAsync([1,2,4], function(item){
console.log(item);
});
You can take this further and use Promises instead of callbacks.

Fibonacci calculator steps

Everything work but I have a question on this Fibonacci calculator (see in-code comment). Could I skip the console.debug step? Why is it needed?
var getFibSum = document.getElementById("sumFib");
getFibSum.onclick = function(){
document.getElementById("sumFibResult").innerHTML = fiftyEvenFibonacciSum();
}
function fiftyEvenFibonacciSum(){
/// WRITE YOUR CODE HERE
var first,second,add;
for(var i=0;i<50;i++){
if(i === 0){
first = 1;
second = 2;
}
/** Why do I have to do the following to make it work?:*/
if(first+second > Number.MAX_VALUE){
console.debug(i, first, second);
return;
}
add = first + second;
first = second;
second = add;
}
return(add);
}
Or would this other way be the most efficient way to write the Fibonacci function to calculate the sum of first 50 numbers:
var getFibSum = document.getElementById("sumFib");
getFibSum.onclick = function(){
document.getElementById("sumFibResult").innerHTML = fiftyEvenFibonacciSum();
}
function fiftyEvenFibonacciSum(){
/// WRITE YOUR CODE HERE
var first,second,add;
for(var i=0;i<50;i++){
if(i === 0){
first = 1;
second = 2;
add = first + second;
first = second;
second = add;
}
return(add);
}
Number.MAX_VALUE is the maximum value your system can address and that part of code actually stops the script and outputs the last numbers in case you go over that max value.
Since you're doing only 50 iterations, it's highly unlikely you'll even come close to that number, so you can freely remove the whole if-clause if it bothers you.
console.debug just prints some debug information, it can be removed safely.

Javascript stop repeating collision detection in canvas

I'm trying to do some simple collisions in javascript and html5 canvas. So far I have this:
checkCollision = (function(){
var l, i, ni,dis = 0;
var ob1,ob2 = {};
return function(){
//collisions is the array holding all the objects
l = collisions.length;
i = 0;
ni = 1;
while(i<l){
//grab the first object
ob1 = collisions[i];
while(ni<l){
//get the object to check against
ob2 = collisions[ni];
//find the distance between the two
dis = Math.sqrt(Math.pow((ob1.pos[0]-ob2.pos[0]),2)+Math.pow((ob1.pos[1]-ob2.pos[1]),2));
//rad is the radius
if(ob1.rad+ob2.rad >= dis){
console.log("collision")
}
//move forward second increment
ni++;
}
i++;
//keep one place ahead
ni=i+1;
}
};
})();
I did it without any help of any kind, but now I guess my brain is too much mush to figure this last part out. The collision is happening every frame, which I don't want. I just want it to fire once when the collision first happens. I've tried by giving each object a collide variable that's true if there's already a collision but it's not working very well. Some it fires once and some it fires constantly.
Does anyone have any pointers?
What do you mean by "happening every frame"? The algorithm seems ok, but there doesn't seem to be any conesquence from the collision, it is just logged. Do you want to break out of the loop?
Some comments that have nothing to do with your issue but might make your code a bit more readable and concise:
> checkCollision = (function(){
> var l, i, ni,dis = 0;
> var ob1,ob2 = {};
I don't know why you initialise dis and ob2, they are assigned values later. Using a closure like this means that the values persist to subesquent calls until new values are assigned. Is the closure really needed? It may be a performance hit for animations like this.
> ni = 1;
> while(i<l){
You can put ni after the while, like this:
while(i < l){
ni = i + 1;
and get rid of the last ni = i + 1. You can also do:
> ob1 = collisions[i++];
and get rid of the last i++;, an do the same for ni when assigning to ob2.
Doing the above reduces the number of lines of code so it is more digestable, e.g.
function checkCollision() {
var ni, dis, ob1, ob2;
//collisions is the array holding all the objects
var l = collisions.length;
var i = 0;
while (i < l) {
ni = i + 1;
//grab the first object
ob1 = collisions[i++];
while (ni < l) {
//get the object to check against
ob2 = collisions[ni++];
//find the distance between the two
dis = Math.sqrt(Math.pow((ob1.pos[0] - ob2.pos[0]), 2) +
Math.pow((ob1.pos[1] - ob2.pos[1]), 2));
//rad is the radius
if (ob1.rad + ob2.rad >= dis) {
console.log("collision");
// And what else?
}
}
}
}

Categories