Javascript for loop displaying more results than expected - javascript

When running the code below, the text inside the document.write runs 8 times and not 7 times as I was expected.
If I understand correctly, increment by 2 should display the positions:
20+2, 22+2, 24+2, 26+2, 28+2, 30+2 and 32+2.
Based on the results I get I assume it also displays the 34+2, which is 36. What I am missing? Thank you.
x = 20;
for (x = 20; x < 35; x += 2) {
document.write("How many times will this loop execute?" + "<br/>");
};

As noted in the comments above, The loop is correct in running 8 times. Since no one stated the reason, it is this: the x+=2 happens at the end of the loop, not at the beginning. So the loop will run for 20, 22, 24, 26, 28, 30, 32, and 34.

You are misunderstanding how the for loop works.
for ([initialization]; [condition]; [final-expression])
final-expression: An expression to be evaluated at the end of each loop iteration. This occurs before the next evaluation of condition. Generally used to update or increment the counter variable.
So your counter gets incremented at the end of the loop and the observed behaviour is correct. The loop gets executed for 20, 22, 24, 26, 28, 30, 32, and 34.

When start loop add +2 to x like below:
x = 20;
for (x = 20+2; x<35; x+=2) {
document.write("How many times will this loop execute?" + "<br/>");
};
fiddle

Script:
x = 20;
count = 1;
for (x = 20; x < 35; x += 2){
document.write("Execution: "+ (count++)+ "<br/>");
};
Output
The loop executes total 8 times.
Execution: 1
Execution: 2
Execution: 3
Execution: 4
Execution: 5
Execution: 6
Execution: 7
Execution: 8
jsfiddle link to checkout.

Yes, is executing 8 times, because is from 20 to 35 in 2 x 2
x = 20;
for (x = 20; x < 35; x += 2) {
document.write("Execute for " + x + " " + "<br/>");
};
/*
OUTPUT:
Execute for 20
Execute for 22
Execute for 24
Execute for 26
Execute for 28
Execute for 30
Execute for 32
Execute for 34
*/
If you want 7 times, you can change to 34
x = 20;
for (x = 20; x < 34; x += 2) {
document.write("Execute for " + x + " " + "<br/>");
};

It will run eight times, x iterating through every even number between 20 and 34 inclusive. You can write it like this if it helps:
var x = 20;
while (x <= 34) {
// do something
x += 2;
}
However, it is important to note that after the loop has run (whether you're using the for or while version), x will equal 36, since it is incremented to that before it finally fails the test; inside the loop, x will never equal 36. In terms of best practice, you should only really use a counter variable like x within the loop; this can be enforced by using the ES6 let keyword (which is block-scoped) like so (the example just prints out a list of the x values as DOM elements):
function appendSpanCounter(i, end) {
let el = document.createElement("span"),
content = i.toString(10);
if (i < end) content += ", ";
(typeof el.textContent === "string") // ternary operator
? el.textContent = content
: el.innerText = content;
(document.body || document.querySelector("body")).appendChild(el);
}
for (let x = 20; x <= 34; x += 2) {
appendSpanCounter(x, 34);
}
// x is now undefined here

Related

How to understand the flow of this JavaScript function

I'm a beginner who is learning JavaScript, after HTML/CSS. I'm at the very beginning of the book of Head First, struggling to understand this function.
How does this function work in every step? What happens starting from thingamajig(5)?
function clunk(times) {
var num = times;
while (num > 0) {
display("clunck");
num = num - 1;
}
}
function thingamajig(size) {
var facky = 1;
clunkCounter = 0;
if (size == 0) {
display("clanck");
} else if (size == 1) {
display("thunk");
} else {
while (size > 1) {
facky = facky * size;
size = size - 1;
}
clunk(facky);
}
}
function display(output) {
console.log(output);
clunkCounter = clunkCounter + 1;
}
var clunkCounter = 0;
thingamajig(5);
console.log(clunkCounter);
Here's what will happen when we run this:
starting from the top, we define three different functions: clunk, thingamajig and display
then we initialize a variable called clunkCounter and assign to it the number 0
then we call the thingamajig function, passing in the argument 5 for the size parameter
in thingamajig, we'll enter the else branch, and we'll end up going through the while loop 4 times, so we're effectively doing facky = 1 * 5 * 4 * 3 * 2, so facky ends up with a value of 120
then we call clunk(120)
so we'll call display("clunk") 120 times
display just logs "clunk", and as a side-effect increments the clunkCounter, to record how many times we've done this
then finally we log out clunkCounter, which will be 120
Why would we want to do this? I don't know. It's a very contrived example which demonstrates how to use if/else conditionals and incrementing variables. I wouldn't worry too much about what it all "means". If you haven't already, try running it in the browser console, and messing around to see what happens if you change the value you pass in to thingamajig.
Edit: Very well explained. Just to add a little, its calculating the Factorial of a number and printing its value at the end.
The main thing to understand for those that still don't get it (like I did not understand when I first looked at this) is that "facky" changes values every time the while loop runs. So if you start with thingamajig(5), facky=5. But then size becomes "size=4" which makes it so you go through the while loop again. THIS TIME facky is going to be "facky=5x4" and therefore it is "facky=20". Then you go through the while loop again with "size=3" which makes it "facky=20x3" and there for it is "facky=60". One last time through the while loop and you get "facky=60x2" and therefore it is "facky=160".
it starts with thingamajig(5);
function thingamajig(size) {
var facky = 1;
clunkCounter = 0;
if (size == 0) {
display("clanck");
} else if (size == 1) {
display("thunk");
} else {
while (size > 1) {
facky = facky * size;
size = size - 1;
}
clunk(facky);
}
}
it takes "5" as parameter which means the "size" variable is 5 and starts to check the conditions in if blocks.
now lets see. the size is 5 so it will skip the first 2 part of the if block
`if (size == 0) {
display("clanck");
} else if (size == 1) {
display("thunk");
}`
and execute the else part
else {
while (size > 1) {
facky = facky * size;
size = size - 1;
}
clunk(facky);
}
this while loop will work until the size > 1 that means the size should be 1 to break the loop. there are some calculations in the while loop.
the "facky" variable changes but in the end the "size" variable will be "1" and the "facky" will be 96
when the "while loop" ends it will call clunk(facky);
that means
`function clunk(96) {
var num = 96;
while (96 > 0) {
display("clunck");
num = num - 1;
}
}`
this function will call "display" function 96 times. and display function will console log "clunck" word for 96 times in the console.
in the end the clucnkCounter will be consoled log.
I hope i understand the question right. because answering this question in writing is hard.
in thingamajig() function the value is passed 5.
and its is checked whether its matches with 0 or 1, then its goes to else block,
here is while loop. facky variable initial value is 1 but here its value is
assign again so its become 5, and size is decremented so become 4
again in while its greater than 1, again 5*4=20, facky become 20.
while continue until size value is 1. when size value is 1, facky become 120.
(5)x(4)x(3)x(2) = 120
now clank function is called and times = 120
here num = times, so num = 120
while num > 0, it call another function display, which console.log(output). And
here output = "clunk".
And increase the value of clunkCounter by 1.
Its keep on repeating until num = 0, and making clunkCounter = 120
-The code starts executing from the else code block in the function thingamajig(size), since the if and else if statement are false.
else {
while (size > 1) {
facky = facky * size;
size = size - 1; }
clunk(facky); }
}
In the else statement we have a while loop with a condition (size > 1), size is 5 inserted as an argument for the size parameter when invoked
thingamajig(5);.
The code loops till size = 1, when the condition becomes false.
LOOP 1,
while size = 5 , facky is = 1, facky = 1 * 5 = 5, size - 1 =size becomes 4.
LOOP 2,
while size = 4, facky = 5, facky = 4 * 5 = 20, size - 1 = size becomes 3.
LOOP 3,
while size = 3, facky = 20, facky = 3 * 20 = 60, size - 1 = size becomes 2.
LOOP 4,
while size = 2, facky = 60, facky = 3 * 60 = 120, size - 1 = size becomes 1.
Before loop stops The clunk() function is invoked and facky is passed as an argument to the times parameter, the function clunk starts executing.
function clunk(times) {
var num = times;
while (num > 0) {
display("clunk");
num = num - 1; }
}
Here, times = facky = 120 = num, The while loop starts executing until num = 0 when the condition becomes false, in this loop the display() function is invoked with the string 'clunk' as an argument.
function display(output) {
console.log(output);
clunkCounter = clunkCounter + 1;
}
The display('clunk') function starts executing.
'clunk' string is copied into the output parameter and it is logged into the console & clunkCounter variable increments.
-The both continues logging string 'clunk' & incrementing clunckCounter, until num = 0, as num decrements from 120 till it gets to 0.
Results
console.log(output);
'clunk' strings logs into the console 120 times.
console.log(clunkCounter);
-clunkCounter increments till its 120 so 120 is logged into the console.

What is the reverse of the Modulo operator

I have hard time wrapping my head around how to get this to work so I came to ask the help of the brilliant minds in here.
The thing is, I want to reverse the process of the below equation so that I get X from the given Y and Z.
Z = [ ( X * 30 ) % Y ]
For the use-case, a user inputs number Y and then presses ENTER, the system get's the current server time and then multiplies that by 30. The user will then be given the remainder of the server time in format HHMMssxxx, (hmm, xxx here is the millisecond.. I don't know the format letter for millisecond.. hehe..), divided by Y - that is (X*30) % Y where X is the current server time converted to int.
How can I do this in reverse?
The catch is, X should not be greater than 2359999 -> (23:59:59.999) the maximum time value for a 24-hour clock.
Supposedly I have Z = 32, Y = 400, how can I find X?
I know that it's possible to have multiple answers. Here's what I came up so far but I think this is not very optimal in terms of performance.
function getTimeIDx(rem, codeIndexer) {
var times = [];
for(var i = 0; i < 2400000; i++) {
if((i * 30) % codeIndexer == rem) {
var str = i.toString(),
l = str.length;
if(l < 9)
str = '000000000'.substr(0, 9 - l) + str;
str = str.substr(0, 2) + ':' + str.substr(2, 2) + ':' + str.substr(4, 2) + '.' + str.substr(6);
if(/^(?:[0-1]?\d|2[0-3]):(?:[0-5]?\d):(?:[0-5]+\d)/.test(str))
times.push(str);
}
}
return times;
}
Is there some way to do this more efficiently? Is there something like a inverse modulo?
EDIT:
Updated code to check if the string is a valid time.
You cannot reverse it. Modulo is the remainder from a division operation.
Simplifying your equation. Z = Y % 2
Z is 0 for half of the values and 1 for the rest.
You can not solve for the dividend with just the remainder and the divisor.
Lets fill it into the equation:
32 = ( X * 30 ) % 400
Then this means that X * 30 is a multiple of 400 plus 32:
32
432
832
...
Now we could divide that by 30 to get x. That could be done in js like this:
function* reverse(Z, Y) {
for(let n = 0; ; n++)
yield (Z + Y * n) / 30;
}
Usable as:
for(let X of reverse(32, 400))
console.log(X);
Note that this loop will run forever as there are infinite results. Try it

Function that returns a multiplication table fails with negative numbers

Hello I was having issue with this function. I wanted to create a function that takes a number, a starting point and a final point, and writes the multiplication table of the number from the starting point to the ending point. For example, tabmul(10,2,4) returns
10.2 = 20
10.3 = 30
10.4 = 40
This is all good but it doesn't work for negative numbers. For example,
tabmul(10,-4,-1) should generate
10.-4 = -40
10.-3 = -30
10.-2 = -20
10.-1 = -10
but it doesn't return anything. This is my code:
function tabmul(a,b,c){ \\function that generates the multiplication table
var myarray = new Array();
var x
for(x=b; x<=c; x++){
myarray[x - b] = a*x;
document.write(a + "." + x + "=" + myarray[x - b] + "<br>")
}
}
var a = prompt("Enter the number whose table you want to calculate: ","");
var b = prompt("Enter the place where you want the table to start","");
var c = prompt("Enter the place where you want the table to end","");
\\ this checks if the starting point is smaller or equal than the ending point of the table
if (0 <= c-b) {
tabmul(a,b,c);
} else {
alert("The starting point is bigger than the ending point");
}
You are comparing strings. This is because prompt returns strings. you need to convert a,b,c to numbers. Also you are using wrong symbols for comments, you need to correct those.
function tabmul(a,b,c){ //function that generates the multiplication table
a = Number(a);
b = Number(b);
c = Number(c);
var myarray = new Array();
var x
for(x=b;x<=c;x++){
myarray[x-b] = a*x;
document.write(a+"."+x+"="+myarray[x-b]+"<br/>")
}
}
var a = prompt("Enter the number whose table you want to calculate: ","");
var b = prompt("Enter the place where you want the table to start","");
var c = prompt("Enter the place where you want the table to end","");
if(0 <= c-b){ //this checks if the starting point is smaller or equal than the ending point of the table
tabmul(a,b,c);
}
else{
alert("The starting point is bigger than the ending point");
}
1)Make normal names for function arguments.
2)Use indentation and 'let' in 'for' loop instead of 'var' right before:
for(let x = b; x <= c; x++){}
3)Don't forget semicolons.
function multiplication(val, start, end) {
if(end - start <= 0) return;
for(let i = start; i <= end; i++) {
console.log(val + ' * ' + i + ' = ' + val * i);
}
}
multiplication(10, -4, -1);
10 * -4 = -40
10 * -3 = -30
10 * -2 = -20
10 * -1 = -10
You should also convert your input to a number using Number or parseInt to make sure it is numeric.
After that you can run into problems referring to an array by index using a negative number.
myarray[x-b] // can fail if x-b<0. Also for a large number n it will insert empty elements in your array up to N.
For example take the following:
var myarray= new Array();
myarray[-4]=1;
console.log(JSON.stringify(myarray));
// result "[]"
myarray= new Array();
myarray[10]=1;
console.log(JSON.stringify(myarray));
// result "[null,null,null,null,null,null,null,null,null,null,1]"
You could convert it to a string:
myarray['"' + (x-b) + '"'] = a*x;
Or you could just use push() and your indexes will start with zero.:
for(x=b;x<=c;x++){
myarray.push(a*x);
document.write(a+"."+x+"="+myarray(myarray.length-1)+"<br/>")
}

Why does it only sums the last two numbers?

I am trying to make a program that sums every number given as parameter. To do so, I wrote the following code:
var x = 0;
var i = 2;
while (isNaN(+process.argv[i + 1]) == false){
x = +process.argv[i] + +process.argv[i + 1];
i++;
}
console.log(x);
The problem is that the code I wrote sums only the 2 last parameter.
I launch my code using node sumArgs.js 1 2 3
and it returns 5.
What is the problem with my code and why isn't it working as planned ?
What is happening every time you loop through, it is taking the current parameter, and the next, and setting x to equal the sum of those.
x needs to be added to, not set. You can do this either:
x += process.argv[i]
or
x = x + process.argv[i]
I'm also not sure why you are adding 2 arguments each loop, as this will cause the sum to be incorrect at the end (unless you increment i twice each loop).
I should note that map reducing it, as in another comment, wouldn't work as the first 2 arguments would not be parameters passed to the program, they would be "node" and "program.js".
var x = 0;
var i = 2;
while (isNaN(+process.argv[i]) == false){
x = x + process.argv[i];
i++;
}
console.log(x);
However, what you could do is use slice:
var sum = process.argv.slice(2).reduce(function(previousValue, currentValue) {
return previousValue + currentValue;
});

Generate all combinations for pair of bits set to 1?

I'm trying to generate all possible combinations for pair of 1's within given bit width.
Let's say the bit width is 6, i.e. number 32. This is what I would like to generate:
000000
000011
000110
001100
001111
011000
011011
011110
110000
110011
110110
111100
111111
If I have variables:
var a = 1,
b = 2;
num = a | b;
and create a loop that I'll loop over width - 1 times, and where I shift both a << 1 and b << 1, I'll get all combinations for one pair. After that, I'm pretty much stuck.
Could someone , please, provide some help.
Update: working example
Based on Barmar's mathematical approach, this is what I managed to implement
var arr = [],
arrBits = [];
function getCombs(pairs, startIdx) {
var i, j, val = 0, tmpVal, idx;
if (startIdx + 2 < pairs) {
startIdx = arr.length - 1;
pairs -= 1;
}
if (pairs < 2) {
return;
}
for (i = 0; i < pairs-1; i++) {
idx = startIdx - (i * 2);
val += arr[idx];
}
for (j = 0; j < idx - 1; j++) {
arrBits.push((val + arr[j]).toString(2));
}
getCombs(pairs, startIdx-1);
}
(function initArr(bits) {
var i, val, pairs, startIdx;
for (i = 1; i < bits; i++) {
val = i == 1 ? 3 : val * 2;
arr.push(val);
arrBits.push(val.toString(2));
}
pairs = Math.floor(bits / 2);
startIdx = arr.length - 1;
getCombs(pairs, startIdx);
console.log(arrBits);
}(9));
Working example on JSFiddle
http://jsfiddle.net/zywc5/
The numbers with exactly one pair of 1's are the sequence 3, 6, 12, 24, 48, ...; they start with 3 and just double each time.
The numbers with two pairs of 1's are 12+3, 24+3, 24+6, 48+3, 48+6, 48+12, ...; these are the above sequence starting at 12 + the original sequence up to n/4.
The numbers with three pairs of 1's are 48+12+3, 96+12+3, 96+24+3, 96+24+6, ...
The relationship between each of these suggests a recursive algorithm making use of the original doubling sequence. I don't have time right now to write it, but I think this should get you going.
if the bit width isn't that big then you'll be way better off creating bit representations for all numbers from 0 to 31 in a loop and simply ignore the ones that have an odd number of "ones" in the bit representation.
Maybe start counting normally in binary and replace all 1's with 11's like this:
n = 5
n = n.toString(2) //= "101"
n = n.replace(/1/g, "11") //= "11011"
n = parseInt(n, 2) //= 27
So you'll get:
0 -> 0
1 -> 11
10 -> 110
11 -> 1111
100 -> 1100
101 -> 11011
110 -> 11110
111 -> 111111
And so on. You'll have to count up to 31 or so on the left side, and reject ones longer than 6 bits on the right side.
See http://jsfiddle.net/SBH6R/
var len=6,
arr=[''];
for(var i=0;i<len;i++){
for(var j=0;j<arr.length;j++){
var k=j;
if(getNum1(arr[j])%2===1){
arr[j]+=1;
}else{
if(i<len-1){
arr.splice(j+1,0,arr[j]+1);
j++;
}
arr[k]+=0;
}
}
}
function getNum1(str){
var n=0;
for(var i=str.length-1;i>=0;i--){
if(str.substr(i,1)==='1'){n++;}
else{break;}
}
return n;
}
document.write(arr.join('<br />'));
Or maybe you will prefer http://jsfiddle.net/SBH6R/1/. It's simpler, but then you will have to sort() the array:
var len=6,
arr=[''];
for(var i=0;i<len;i++){
for(var k=0,l=arr.length;k<l;k++){
if(getNum1(arr[k])%2===1){
arr[k]+=1;
}else{
if(i<len-1){
arr.push(arr[k]+1);
}
arr[k]+=0;
}
}
}
function getNum1(str){
var n=0;
for(var i=str.length-1;i>=0;i--){
if(str.substr(i,1)==='1'){n++;}
else{break;}
}
return n;
}
document.write(arr.sort().join('<br />'));
See http://jsperf.com/generate-all-combinations-for-pair-of-bits-set-to-1 if you want to compare the performance. It seems that the fastest code is the first one on Chrome but the second one on Firefox.
You can also do this with bit twiddling. If the lowest two bits are zero, we need to set them, which is equivalent to adding 3. Otherwise, we need to replace the lowest block of ones by its top bit and a 1-bit to the left of it. This can be done as follows, where x is the current combination:
x3 = x + 3;
return (((x ^ x3) - 2) >> 2) + x3;

Categories

Resources