Javascript XOR operation (trying to understand!) - javascript

I've been researching the caret (XOR) operator in Javascript, but i'm having a heck of a hard time understanding.
Can someone explain why, for example, 1 ^ 1 = 0?
I have some code someone wrote, and they are doing the following:
if (shouldBeCollapsed ^ 1)
{
//code to collapse section of page.
}
But if the shouldBeCollapsed variable is equal to 1, the condition fails. I'm just trying to understand the logic behind the ^ operator, and it's kind of confusing me!
Thanks!

That is the definition of XOR. X ^ Y is 1 iff X != Y.
Thus, if X and Y are both 1, then XOR is 0.
The truth table is as follows:
X Y X^Y
0 0 0
0 1 1
1 0 1
1 1 0
X ^ Y is logically equivalent to (X && !Y) || (!X && Y)

Let me illustrate with an example:
2 ^ 1 = 3
In binary
10 ^ 01 = 11
At a bitwise level, A^B = 1 if A != B
shouldBeCollapsed looks like a boolean variable in which case you are doing it wrong. What you are looking for is :
if (shouldBeCollapsed) {
// Code to collapse
}

Related

Whats the shortest way to return a condition as 1 and -1

Is there any shorter way to return a condition as 1 if true/truthy and -1 if false/falsy? Maybe using bitwise operators?
The shortest way I can think is:
condition?1:-1
Just take
+condition || -1
where condition is a boolean value.
Assuming condition is a boolean value, we can golf one character:
condition*2-1
(Not that I would recommend to write code like this…)
there's gotta be a shorter way to do than i + (i%2==0?1:-1)
What you actually want is to just toggle the last bit in the number, which can be achieved with XOR:
i^1
Simply you can try the folowing:
condition ^ (condition - 1)
So when condition is true then that would be:
1 ^ (1 - 1)
=> 1 ^ 0
=> 1
And when condition is false then:
0 ^ (0 - 1)
=> 0 ^ -1
=> -1
Hope this helps.
I see those ones :
(for the funny transformation)
// #1
let boolToNumber = b=> +b*2-1;
// #2
boolToNumber = b => (b<<1)-1;
// #3
boolToNumber = b => b?+b:~b;
And if what really matter for you is the size, make it an 1 char function
//
let boolToNumber = b=> +b*2-1;
let b = boolToNumber;
let c = true;
b(c)// 4 charaters

Print all possible strings that can be made by placing spaces

I came across this problem.
Print all possible strings that can be made by placing spaces.
I also came across this solution.
var spacer = function (input) {
var result = '' ;
var inputArray = input.split('');
var length = inputArray.length;
var resultSize = Math.pow(2,length-1); // how this works
for(var i = 0 ; i< resultSize ; i++){
for(var j=0;j<length;j++){
result += inputArray[j];
if((i & (1<<j))>0){ // how this works
result += ' ' ;
}
}
result += '\n' ;
}
return result;
}
var main = function() {
var input = 'abcd' ;
var result = spacer(input);
console.log(result);
}
main();
I am not getting how the marked lines work?
Can you clarify on what technique is being used? And what is the basic logic behind this? What are some of other areas where we can use this?
Thanks.
Let's take string abcd as an example.
There are 3 possible places where space can be put:
Between "a" and "b"
Between "b" and "c"
Between "c" and "d"
So generally if length of your string is length then you have length - 1 places for spaces.
Assume that each such place is represented with a separate digit in a binary number. This digit is 0 when we don't put space there, and 1 when we do. E.g.:
a b c d
0 0 0 means that we don't put any spaces - abcd
0 0 1 means that we put space between "c" and "d" only - abc d
0 1 0 means that we put space between "b" and "c" only - ab cd
0 1 1 means ab c d
1 0 0 means a bcd
1 0 1 means a bc d
1 1 0 means a b cd
1 1 1 means a b c d
Converting 000, 001, 010, ..., 111 from binary to decimal will give us values 0, 1, 2, ..., 7.
With 3 places for spaces we have 8 options to put them. It's exactly 2^3 or 2^(length - 1).
Thus we need to iterate all numbers between 0 (inclusive) and 2^(length - 1) (exclusive).
Condition (i & (1 << j)) > 0 in the code you provided just checks whether digit at position j (starting from the end, 0-based) is 0 (and we don't need to insert space) or 1 (and space should be added).
Let's take value 6 (110 in binary) for example.
(6 & (1 << 0)) = 110 & 001 = 000 = 0 (condition > 0 is not met)
(6 & (1 << 1)) = 110 & 010 = 010 = 2 (condition > 0 is met)
(6 & (1 << 2)) = 110 & 100 = 100 = 4 (condition > 0 is met)
simple solution Using Javascript
String.prototype.splice = function(idx, rem, str) {
return this.slice(0, idx) + str + this.slice(idx + Math.abs(rem));
};
function printPattern(str, i, n){
if(i==n){
return;
}
var buff = str;
var j = str.length - n + i;
buff = str.splice(j,0," ");
console.log(buff);
printPattern(str, i+1, n);
printPattern(buff, i+1, n);
}
var str = "ABCD"
printPattern(str, 1, str.length);
console.log(str);
There are 2 possibilities between each 2 characters: either has space or not. If spaces are allowed only between characters then the number of possibilities for 4 characters is 2 * 2 * 2 or 2 ^ (length - 1)
resultSize = Math.pow(2, length - 1) says there are 2^n-1 possible ways to print a string given the problem definition. As far as to why that is the number of solutions is pretty easy to understand if you start with a string that has 2 characters and work your way upward. So pretend you have the string "ab". There is two solutions, you can put a space between a and b or you can not put a space between a and b. Lets add a character to get "abc". Well, we already know that there are two solutions for the string "ab" so we need multiply that solution by the number of ways you can put a space between b and c. Which is 2 so that gives us 2 * 2 solutions. You can extend that to a string of n size. So that means that the number of solutions is 2 * 2 * 2 * 2 * ... n - 1. Or in otherwords 2 ^ n-1.
The next part is a little trickier, but its a clever way of determining how many spaces and where they go in any given solution. The bitwise & takes the each bit of two numbers, compares them, then spits out a new number where each bit is a 1 if both the bits of the two numbers were 1, or 0 if the bits were not 1 and 1. For example (binary numbers):
01 & 01 = 01
10 & 01 = 00
Or a bigger example:
10010010 & 10100010 = 10000010
The << operator just moves all bits n position to left where n is the right hand expression (multiply by 2 n times).
For example:
1 << 1 = 2
2 << 1 = 4
2 << 2 = 8
1 << 4 = 8
So back to your code now. Lets break down the if statement
if(i & (1 << j) > 0){ ... }
In english this says, if the number index of the solution we are looking at shares any 1 bits with 1 shifted by the index of the character we are looking at, then put a space after that character. Olexiy Sadovnikov's answer has some good examples of what this would look like for some of the iterations.
Its also worth noting that this is not the only way to do this. You could pretty easily determine that the max number of spaces is n - 1 then just linearly find all of the solutions that have 0 spaces in them, then find all the solutions that have 1 space in them, then 2 spaces .... to n - 1 spaces. Though the solution you posted would be faster than doing it this way. Of course when your talking about algorithms of exponential complexity it ultimately won't matter because strings bigger than about 60 chars will take longer than you probably care to wait for even with a strictly 2^n algorithm.
In answer to the question of how these techniques can be used in other places. Bit shifting is used very frequently in encryption algorithms as well as the bitwise & and | operators.
'''
The idea was to fix each character from the beginning and print space separated rest of the string.
Like for "ABCD":
A BCD # Fix A and print rest string
AB CD # Add B to previous value A and print rest of the string
ABC D # Add C to previous value AB and print rest of the string
Similarly we can add a space to produce all permutations.
Like:
In second step above we got "AB CD" by having "A" as prefix
So now we can get "A B CD" by having "A " as a prefix
'''
def printPermute(arr, s, app):
if len(arr) <= 1:
return
else:
print(app +''+arr[0:s] +' '+ arr[s:len(arr)])
prefix = app + ''+arr[0:s]
suffix = arr[s:len(arr)]
printPermute(suffix, 1, prefix)
printPermute(suffix, 1, prefix+' ') #Appending space
printPermute("ABCDE", 1, '') #Empty string
.pow is a method from Math which stands for "power". It takes two arguments: the base (here 2) and the exponent. Read here for more information.
& is the bitwise AND operator, it takes the two binary representation of the numbers and performs a logical AND, here's a thread on bitwise operators
EDIT: why Math.pow(2,length-1) gives us the number of possible strings?
I remember doing it in an exercise last year in math class, but I'll try to explain it without sums.
Essentially we want to determine the number of strings you can make by adding one or no space in between letters. Your initial string has n letters. Here's the reason why:
Starting from the left or the word after each letter you have two choices
1 - to put a space
2 - not to put a space
You will have to choose between the two options exactly n-1 times.
This means you will have a total of 2^(n-1) possible solutions.

Why is my for loop with (4^i >= x) as condition becoming infinite in JavaScript? [duplicate]

I have some JavaScript code:
<script type="text/javascript">
$(document).ready(function(){
$('#calcular').click(function() {
var altura2 = ((($('#ddl_altura').attr("value"))/100)^2);
var peso = $('#ddl_peso').attr("value");
var resultado = Math.round(parseFloat(peso / altura2)*100)/100;
if (resultado > 0) {
$('#resultado').html(resultado);
$('#imc').show();
};
});
});
</script>
What does the ^ (caret) symbol mean in JavaScript?
The ^ operator is the bitwise XOR operator. To square a value, use Math.pow:
var altura2 = Math.pow($('#ddl_altura').attr("value")/100, 2);
^ is performing exclusive OR (XOR), for instance
6 is 110 in binary, 3 is 011 in binary, and
6 ^ 3, meaning 110 XOR 011 gives 101 (5).
110 since 0 ^ 0 => 0
011 0 ^ 1 => 1
--- 1 ^ 0 => 1
101 1 ^ 1 => 0
Math.pow(x,2) calculates x² but for square you better use x*x as Math.pow uses logarithms and you get more approximations errors. ( x² ~ exp(2.log(x)) )
Its called bitwise XOR. Let me explain it:
You have :
Decimal Binary
0 0
1 01
2 10
3 11
Now we want 3^2= ?
then we have 11^10=?
11
10
---
01
---
so 11^10=01
01 in Decimal is 1.
So we can say that 3^2=1;
This is the bitwise XOR operator.
The bitwise XOR operator is indicated
by a caret ( ^ ) and, of course, works
directly on the binary form of
numbers. Bitwise XOR is different from
bitwise OR in that it returns 1 only
when exactly one bit has a value of 1.
Source: http://www.java-samples.com/showtutorial.php?tutorialid=820

iterating a selection in javascript

This is a simple code to change the style of even numbered list elements but as a newbie, i really did not understand how the following if statement can be true and false. Because i think that key is always true. However, when i run the code, i see that it is not always true. Can someone explain why?
$(document).ready(
function()
{
$('ul#rubberSoul li').each(
function(key)
{
if (key & 1) {
$(this).addClass('rubberSoulEven');
}
}
);
}
);
& operator does a bitwise AND operation on each of the bits of two 32 bit expression (the operands). If the bit value from both the sides are 1, the result is 1. Otherwise, the result is 0. Bitwise ANDing any number with 0 yields 0
For example , take this expression x & y
x value y value result
-----------------------------
1 1 1
1 0 0
0 1 0
0 0 0
So in your case, it is going to check bit representation of key variable value & bit representation of 1 in your if condition and return the result of that.
operand1(key) operand1-binary operand2 operand2-binary result
------------------------------------------------------------------
1 1 1 1 1
2 10 1 01 0
3 11 1 01 1
4 100 1 001 0
key is index of each and (key & 1) is true for odd indexes.
<ul id="rubberSoul ">
<li class="">One</li> # 0
<li class="">Two</li> # 1
<li class="">Three</li> # 2
</ul>
Your If loop will show true for only the second statement (<li class="">Two</li> # 1) as it validates (if (key & 1))

Javascript expression: double greater than x and greater than y

So I wondered to myself if there is a way to do a double greater than, like this:
if(x > y > z) { ... }
Then I saw this
Expression for "more than x and less than y"?
But then I tried the following expression in the console and got a weird result:
(5 < 2 < 1) // returned true
(5 > 2 > 1) // returned false
How?
Update: I know that you can't do this "(x > y > z)", just wanted explanation on the weird result.
You need two separate conditions, such as 5<2 && 2<1 for this to do what you're after. Without two conditions, you are comparing the result of the first condition against the right side of the second condition.
Why?
For the unexplained behaviour, I believe that the explanation for why it's returning what it's returning is the way javascript handles booleans (among other things) when used in numerical operations, in other words, javascript will cast your booleans to 0 or 1, there are a lot of examples of this in a few questions here at so, for example this one, you could do +false and get a 0 for instance.
(5 < 2 < 1) is true because:
5<2 is resolved first, returning false
false is cast to a number, returning 0
0<1 will return true
(5 > 2 > 1) is false because:
5>2 is resolved first, will return true
true is cast to a number, will return 1
1>1 will return false
No. You can't do this in JavaScript. Much as it would be useful, you're stuck with x > y && y > z.
That said, to explain your result:
5 < 2 gives false
false casts to 0
0 < 1 is true
And:
5 > 2 gives true
true casts to 1
1 > 1 is false
As far as a "way to do a double greater than", you could define a function:
function gt () {
var prev = arguments[0];
return !([].slice.call(arguments, 1).some(function (arg) {
var ret = prev <= arg;
prev = arg;
return ret;
}));
}
...then call like this:
if(gt(x, y, z)) { ... }
I would just try if((5>2) && (2>1)) {
} not sure why the other one didnt work but thus implementation should be a proper substitute for code that could be written in the other way you have it.

Categories

Resources