What is the use of a bitwise and, (&1), in javascript? - javascript

From the tutorial here,
function notePressed(event) {
if (event.buttons & 1) {
let dataset = event.target.dataset;
if (!dataset["pressed"]) {
let octave = +dataset["octave"];
oscList[octave][dataset["note"]] = playTone(dataset["frequency"]);
dataset["pressed"] = "yes";
}
}
}
What is the use of event.buttons & 1? Why is a bitwise AND being used?

Here event.buttons returns an integer value, which represents that which mouse button is pressed. According to MDN it returns -
0 : No button or un-initialized
1 : Primary button (usually the left button)
2 : Secondary button (usually the right button)
4 : Auxiliary button (usually the mouse wheel button or middle button)
8 : 4th button (typically the "Browser Back" button)
16 : 5th button (typically the "Browser Forward" button)
So, ultimately what do we get from this event.buttons? An integer value.
Now come to your shared code snippet. What does the line if (event.buttons & 1) mean? Let's check some example of, what does the & 1 do with 32 bits integer.
0 & 1 => 0
1 & 1 => 1
2 & 1 => 0
3 & 1 => 1
23 & 1 => 1
46 & 1 => 0
So, if we perform & 1 with any 32 bits integer number then for Even numbers it returns 0 and for Odd numbers it returns 1. We can easily detect any odd/even numbers by using bitwise AND 1 operation.
Now you know 0 is a falsy value so the if condition never passes if we get 0 from the statement. So, if (event.buttons & 1) checks if the event.buttons gives an Odd number then execute the if block, otherwise not.
I hope I can clear it.

Related

dont allow typing if decimal point is already 2

The use case is a user is allowed to input number that has decimal point less than either 2 or 1. For e.g these are the valid ones;
10.12
10.1
10.00
10
but 10.123 is invalid
I am able to do this in two different way. One using regex pattern and other by getting the position of decimal and checking how many digits are there after decimal. This way actually its working however I am facing one strange issue. The issue is when I type 10.11 and then type 2 it wont allow and if I again type 2 it will then be 10.112 but instead of typing 2 for consecutively second times If I type 3 then it wont be 10.113 rather stay in 10.11
This is how I have done
<FormulateInput
name="height"
type="number"
step=".01"
placeholder="0.0"
v-model="height"
:value="getHeightValue"
:disabled="disableHeight"
#input="updateField('height', $event)"
min="0"
/>
updateField(field, value) {
const numberOfDecimal = (field === 'height' || field === 'depth') ? 3 : 2
// const nonDecimalValue = (value.indexOf(".") >= 0) ? value.substr(0, value.indexOf(".")) : value
// const decimalValue = (value.indexOf(".") >= 0) ? value.substr(value.indexOf("."), value.length) : ''
// if (decimalValue?.length > 3) {
// debugger
// this[field] = parseFloat(value).toFixed(2)
// }
this[field] = (value.indexOf(".") >= 0) ? (value.substr(0, value.indexOf(".")) + value.substr(value.indexOf("."), numberOfDecimal)) : value;
// this[field] = +value < 0 ? 0 : value;
},
It seems like;
when I type 1 it goes to updateField
when I type .1 it again goes to updateField and value gets updated to this[field]
when I type 2 it again goes to updateField and value gets updated to the state
when I type 2 then it sees the decimal digit as 3 so it does not get updated to the state but value on forumlate is 1.122 so if I again type 2 then it does not see any changes so updateField does not get triggered so it shows 1.122. Instead if I type 3 or any digit other than 2 then it does not show 3 digits after decimal.
I hope I made my problem clear. Sorry if its confusing.
I am using vue-formulate for my form.

Find numbers that have specified data about people

There is an array of binary numbers that are created in this order
the first number means whether the person is on vacation: 1/0
the second set of 8 numbers means the worker's age: 255 maximum (11111111)
the third set of 4 numbers means how many vacations are left: maximum 15 vacations (1111)
How to find:
all worker on vacation, aged 20-30 inclusive
all worker are not on vacation with the number of vacation 10 or more
An array of workers data:
let workers = [
0b1000101001001,
0b1000101111011,
0b1000111101011,
0b0000101101010,
0b0000111011111,
0b0000110011110,
0b1001000011001,
0b1001000011001,
0b0000101101000,
0b0000101100100,
];
To know whether the number i encodes "on vacation" or not, evaluate:
i >= 0x1000
If this is true, that worker is on vacation
To know the age that the number i encodes, evaluate:
(i >> 4) & 0xFF
To know the number of vacation days that is encoded, evaluate:
i & 0xFF
The rest should be simple to do.
all workers on vacation, aged 20-30 inclusive
let workers = [0b1000101001001, 0b1000101111011, 0b1000111101011, 0b0000101101010, 0b0000111011111, 0b0000110011110, 0b1001000011001, 0b1001000011001, 0b0000101101000, 0b0000101100100, ];
let result = workers.filter(i => {
let onVac = i >= 0x1000;
let age = (i >> 4) & 0xFF;
return onVac && age >= 20 && age <= 30;
});
console.log(result.map(num => num.toString(2)))
all workers that are not on vacation with the number of vacation 10 or more
let workers = [0b1000101001001, 0b1000101111011, 0b1000111101011, 0b0000101101010, 0b0000111011111, 0b0000110011110, 0b1001000011001, 0b1001000011001, 0b0000101101000, 0b0000101100100, ];
let result = workers.filter(i => {
let onVac = i >= 0x1000;
let numVac = i & 0xFF;
return !onVac && numVac >= 10;
});
console.log(result.map(num=>num.toString(2)))
Sometimes you can filter with fewer operations, but this at least shows clearly the final expression that is evaluated in the filter callback.
Other patterns
In general, to extract a part of a bitpattern, you first shift the input and then AND it. Here the part to extract is indicated with ^:
input = 0b1111111111111111111111111
^^^^^^^^
← 8 →← 7 →
First count the number of bits (digits) that are at the right of the section you need. In this case there are 7 bits to the right of the ^-marked section. This determines how many times you need to shift with the >> operator.
Then you count the number of bits that are in the section of interest. In this case the ^ section has a width of 8 bits. Now make a number that has 8 bits, and all of them 1-bits: 0b11111111. You can of course choose to write it in hexadecimal or in decimal, ... it doesn't matter, as long as the value is the same. This number will be the number you perform the AND (&) operation with.
So in the above example, you combine as follows:
(input >> 7) & 0b11111111
There are of course a few cases where you can shorten this expression:
Extract left most bits
If the section you need, is the left-most section in the bit pattern, then the AND-operation is not needed:
input = 0b1111111111111111111111111
^^^^^^^^
← 8 →← 17 →
Here both of the following give the same result:
(input >> 17) & 0b11111111
input >> 17
Extract right most bits
If the section you need, is the right-most section in the bit pattern, then the AND-operation is not needed:
input = 0b1111111111111111111111111
^^^^^^^^
← 8 →
Here both of the following give the same result:
(input >> 0) & 0b11111111
input & 0b11111111
Extract left most bit -- just one bit
If the section you need, is the left-most single bit in the bit pattern, then you can also use a greater-or-equal comparison to return a boolean:
input = 0b1111111111111111111111111
^
← 24 →
You can know whether this bit it set with a comparison. Here all of the following give a useful same result:
(input >> 24) & 0b1
input >> 24
input >= 0b1000000000000000000000000
...but with one difference: the third evaluates to a boolean, while the other two evaluate to a 0 or a 1.
Decrypt:
function decrypt(bin, encriptDigitsArray) {
var result=[];
while(bin!="" && encriptDigitsArray.length) {
result.push(parseInt(bin.slice(0,encriptDigitsArray[0]), 2));
bin=bin.slice(encriptDigitsArray[0]);
encriptDigitsArray.shift();
}
return result;
}
console.log(decrypt("0001111011011",[8,4,1]));
console.log(decrypt("000111101101",[8,4,1]));
console.log(decrypt("00011110",[8,4,1]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Answered here for you other question here.

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.

& 1 JavaScript. How does it work? Clever or good? [duplicate]

This question already has answers here:
Is there a & logical operator in Javascript
(8 answers)
Closed 6 years ago.
I'm looking over the solutions for a CodeWars problem (IQ Test) in which you're given a string of numbers and all the numbers but 1 are either even or odd. You need to return the index plus 1 of the position of the number that's not like the rest of the numbers.
I'm confused about the line that says & 1 in the solution posted below. The code doesn't work w/ && or w/ the & 1 taken away.
function iqTest(numbers){
numbers = numbers.split(' ')
var evens = []
var odds = []
for (var i = 0; i < numbers.length; i++) {
if (numbers[i] & 1) { //PLEASE EXPLAIN THIS LINE!
odds.push(i + 1)
} else {
evens.push(i + 1)
}
}
return evens.length === 1 ? evens[0] : odds[0]
}
Also, would you consider using & 1 to be best practice or is it just "clever" code?
The single & is a 'bitwise' operator. This specific operator (&) is the bitwise AND operator - which returns a one in each bit position for which the corresponding bits of both operands are ones.
The way it's being used here is to test if numbers[i] is an even or odd number. As i loops from 0 to numbers.length, for the first iteration the if statement evaluates 0 & 1 which evaluates to 0, or false. On the next iteration of the loop, the statement will be 1 & 1, which evaluates to 1, or true.
The result - when numbers[i] & 1 evaluates to 0, or false, then numbers[i] is pushed to the odd array. If numbers[i] & 1 evaluates to 1, or true, then numbers[i] is pushed to the even array.
An alternative to the & operator to test for even and odd is to use the modulo operator. numbers[i] % 2 results in the same output. That is, 1 % 2 results in 1, or true as will any odd number, because an odd number divided by 2 results in a remainder of 1. And any even number, like 2 % 2 results in 0 or false because an even number divided by 2 results in a remainder of 0.
As for your second question, is it 'clever or good?'. It's definitely clever. Whether it's good depends on who you ask and what your goal is. Many would say its less logical and harder to read than using num % 2.
Binary number is 0 and 1 and each of them is called bit.
Single & is add operation and it works bitwise.
like
1 = 01
2 = 10
3 = 11
4 = 100
You can see that every last bit of odd number is 1 and even number is 0.
In add operation
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
So only odd number will return 1 and even number will return 0 and in programming only 0 consider falsy.
If we wanna to check 5 is a odd or even
5 = 101
and perform and(&) operation with 1
101
& 001
-----
001
and value of binary 001 is 1 in 10 base number
So it'll perform easy odd even process.

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))

Categories

Resources