I try to solve this problem
"Consider an array of non-negative integers. A second array is formed by shuffling the elements of the first array and deleting a random element. Given these two arrays, find which element is missing in the second array."
And one of the solution is below code using XOR
def find(arr1, arr2):
result=0
# Perform an XOR between the numbers in the arrays
for num in arr1+arr2:
result^=num
print result
return result
arr1 = [1,2,3,4,5,6,7]
arr2 = [3,7,2,1,4,6]
The result of the function is 5.
I know the basic principle of XOR. But I can't understand how the above code can find the result.
Some important concepts:
XOR of a number with itself is always 0
XOR of a number with 0 is always the number itself
The order of an XOR operation is inconsequential
With this, consider:
1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 3 ^ 7 ^ 2 ^ 1 ^ 4 ^ 6
→ (1 ^ 1) ^ (2 ^ 2) ^ (3 ^ 3) ^ (4 ^ 4) ^ (5) ^ (6 ^ 6) ^ (7 ^ 7)
→ 0 ^ 0 ^ 0 ^ 0 ^ 5 ^ 0 ^ 0
→ 5
And so, the odd one out remains.
You start with the result = 0
Then you keep XORing the result with all the elements of each array. The XOR flips all the nonzero bits of the number you currently have.
So when you encounter the same number twice, you have flipped the same set of bits twice - meaning that you are back at the state you started with.
Every number that appears in both lists ends up "canceling itself". The only number that is not canceled is the one that is missing from the second list.
It doesn't matter what each integer is - the bits will flip twice if the number appears twice, and once if the number appears once. It doesn't even matter if the number is missing in the first or the second array.
Related
I was asked to find out the number from a list of numbers in Python that is present only once inside the list. As usual, I could easily solve it using the normal method that immediately comes out:
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
for i in nums:
if(nums.count(i) == 1):
return i
return nums[0]
Trying to find out another better way, Internet suggested me to use Bitwise XOR operation and provided the following code which was way faster and more efficient. Below is the code:
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
a = 0
for i in nums:
a^=i
print(a)
return a
The logic was if we do a XOR operation on 2 same bits(0,0 or 1,1) the answer will always be 0 and it will be 1 if the bits are different. Using this, it came out with such an approach.
My mind bogs down at trying to realize how is the normal concept of XOR operation coming to be useful here! I understand the logic they said about that same and different bits but by their code, every time I perform a XOR with the next bit a new number pops out so how can then we guarantee that only the number which occurs once will be evolved?
I feel clueless. It might not be a good approach to have posted a code snippet and then ask for an explanation but I feel the solution is extremely intriguing and am dying to learn how bitwise XOR helped out! Please help if anyone has an idea! Thanks in advance.
Note : In the list, all numbers occur twice except for one.
The general constraints for this XOR solution are a bit different:
You have a list where exactly one number occurs an odd number of times and all other numbers occur an even number of times and need to find the odd one.
XOR flips the bits if they are identical:
b1 XOR b1 > b0
b0 XOR b0 > b0
b1 XOR b0 > b1
b0 XOR b1 > b1
You have an arbitrary start value (the first number in your list), f.e.:
01010111011111101
If all other numbers occur an even number of times, you see each bit pattern at least twice.
The first time you have pairs of bits and
flip every 0,1 bit to 1
flip every 1,0 bit to 1
flip every 1,1 bit to 0
then you encounter the same number again (because number even times in it):
you have a 1 bit from last flipping and encounter a 1 bit again so you flip to 0
you have a 1 bit from last flipping and encounter a 0 bit again so you stay at 1
you have a 0 bit from last flipping and encounter a 1 bit again so you flip to 1
and you are now back at your original number because even times occuring numbers cancel out:
101010010
xor 101010010
-------------
000000000
and if you XOR any other number with 000000000 you get exactly that other number back.
The relevant properties of the XOR operation are:
It is associative, so (a ^ b) ^ c == a ^ (b ^ c)
It is commutative, so a ^ b == b ^ a
It has 0 as an identity element, so a ^ 0 == 0 ^ a == a
Every element is its own inverse, so a ^ a == 0
So consider what happens when your input list is like [3, 4, 5, 4, 3]. From the first two properties, we have that (((3 ^ 4) ^ 5) ^ 4) ^ 3 is the same as (3 ^ 3) ^ (4 ^ 4) ^ 5, from the fourth property this is the same as 0 ^ 0 ^ 5, and from the third property the result is 5. Effectively, every element which appears an even number of times cancels out with itself, leaving just the element which occurs once (or an odd number of times).
I think without knowing the properties of XOR operation, it is difficult to understand what that code does
This is the property of XOR operation
If the bits are the same, the result is 0. If the bits are different, the result is 1.
Below table will give a clear idea of the above XOR property.
+---+---+---------+
| a | b | a XOR b |
+---+---+---------+
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
+---+---+---------+
The Solution to your question is based on this concept.
An interesting property of XOR is that
when you XOR the same number by itself even number of times you get a Zero
when you XOR the same number by itself odd number of times you get the number itself
Take for example - Number 2 (2 in binary is - 0010)
Let us
Perform XOR of 2 (even no. times)
0010
0010
----
0000 <- XOR (Value is 0)
Perform XOR of 2 (odd number of times)
0010
0010
0010
----
0010 <- XOR (Value is 2)
Whatever numbers are occuring for even number of times will eventually result in a Zero and Zero XORed with the number occuring odd number of times will give you the same number (that occurs odd number of times)
And the reason why a is initialized to 0 is because - 0 XOR x will give x itself
Say x = 3
0 -> 0000
3 -> 0011
----
0011 <- XOR (Value is 3)
Edit - Based on OP's doubt
For the input arr = [1,2,2,4,1] you are asking why you are getting arbitrary values - 1,3,1,5,4
They are not arbitrary. They are the result of XOR operation between a and i.
Initial value of a = 0
First Iteration: i = 1(0001); a = 0 (0000)
i: 0000
a: 0001
----
0001 -> Decimal value is 1 stored in a
Second Iteration: i = 2(0010); a = 1 (0001)
i: 0010
a: 0001
----
0011 -> Decimal value is 3 stored in a
Third Iteration: i = 2(0010); a = 3 (0011)
i: 0010
a: 0011
----
0001 -> Decimal value is 1 stored in a
Fourth Iteration: i = 4(0100); a = 1 (0001)
i: 0100
a: 0001
----
0101 -> Decimal value is 5 stored in a
Fifth Iteration: i = 1(0001); a = 5 (0101)
i: 0001
a: 0101
----
0100 -> Decimal value is 4 stored in a
Given an n-bit integer, I want to find the set of n-bit integers which are related to my original integer by the interchange of a single 1 by a single 0 where the interchanged 1 and 0 must be adjacent
So what I want is to find some function such that for example, if I gave it the binary 1011 (11 in base 10) it returns 0111 and 1101 (7 and 13 in base 10)
ie. so this would look like:
>>> bit_hop(11, n=4)
[7, 13]
It's important that this function knows how many bits the number is because my other constraint is that I need this to have periodic boundary conditions such that for example 0111 would return not only 1011 but also 1110, ie. the edges of the binary number should be adjacent.
Also, as said, only one swapping should be allowed per hop. This means that bit_hop(1010) should return [1100, 0011, 1001, 0110]
Does anyone have any ideas on how one might go about doing this? I know that this should involve some clever usage of the >>, << and ^ operations but I'm having trouble seeing the synthesis.
To do this directly in binary, you have to notice a couple of things about the algorithm. First it always deals with adjacent bits, except for looping around from the first bit to the last. Second those bits must be different, if they're the same swapping them wouldn't do anything.
This code walks a 2-bit mask around the value and tests to see if the bits are different, then uses exclusive-or to swap them.
def bit_hop(x, n):
for i in range(n-1):
mask = 3 << i
if x & mask != 0 and x & mask != mask:
yield x ^ mask
mask = (1 << (n-1)) | 1
if x & mask != 0 and x & mask != mask:
yield x ^ mask
I really do not know how to figure it out!!!
remove_middle_character("apple")
'aple'
remove_middle_character("banana")
'bana'
remove_middle_character("discount")
‘disunt‘
”“”
Since it's probably classwork, I'm not going to give you the code (which you would be unwise using anyway since your educational institution probably knows about Stack Overflow and would catch you out with plagiarism). Instead, I'll provide guidance on what you need to know.
If the string or of size two or less (we handle this early so that we don't have to worry about edge cases in the following steps), just return an empty string.
Otherwise, if the length of the string is odd, get the length x, and return the first x // 2 (the // operator is integer division) characters concatenated with the character starting at x // 2 + 1.
Otherwise, return the first x // 2 - 1 characters concatenated with the characters starting at x // 2 + 1.
In terms of turning that into code:
you can get the length of a string x with len(x);
you can get the first n characters with x[:n];
you can get the characters starting at m with x[m:];
you can concatenate strings with +; and
you can test if a value p is even by using if (p % 2) == 0 (and, of course, odd numbers will cause (p % 2) == 1 to evaluate as true).
That should be all you need to write the code yourself.
Using all the excellent suggestions above, I suggest a refactored approach where the edge conditions mentioned by paxdiablo and enhanced by mhawke are catered for but remove the need for using an if-else statement.
As you can see from paxdiablo if the string length is odd (the modulo function returns 1) the fist part of the string is:
x // 2 (subtract 0).
If the string length is even (the modulo function returns 0) the fist part of the string is:
x // 2 - 1 (subtract 1).
In both cases (odd and even length), the second part of the string is:
x // 2 + 1
So we need to subtract the reverse of what the modulo 2 of the string length would give us. We can do this by making an even length odd and an odd length even. One possible way is: mod = (len(s) + 1) % 2. So a possible solution might look like:
def remove_middle_character(s):
h = len(s)//2
mod = (len(s) + 1) % 2
return s[:h - mod] + s[h + 1:]
if __name__ == "__main__":
print(remove_middle_character(""))
print(remove_middle_character("x"))
print(remove_middle_character("xy"))
print(remove_middle_character("apple"))
print(remove_middle_character("banana"))
print(remove_middle_character("discount"))
This question already has answers here:
How to do a bitwise NOR Gate in Python (editing python maths to work for me)
(2 answers)
Closed 9 years ago.
I'm trying to understand the code from an answer I received yesterday:
2nd: How to make a bitwise NOR gate
1st: How to do a bitwise NOR Gate in Python (editing python maths to work for me)
a=0b01100001
b=0b01100010
bin((a ^ 0b11111111) & (b ^ 0b11111111))
I now understand EVERYTHING except:
the & between the two values
and the ^ 11111111 ( I know that 0b is base 2)
Can someone please explain these?
How NOR works?
The expression x NOR y can be broken using AND, OR, and NOT:
x NOR y == NOT(x OR y) == NOT(x) AND NOT(y)
So, for your given values:
a=0b01100001
b=0b01100010
a NOR b would be NOT(a) AND NOT(b). Now think how would you do a NOT(a)? You just need to flip the bits. What is the way to flip the bits? An XOR(^). How?
0 ^ 1 == 1
1 ^ 1 == 0
So, taking the XOR of any bit with 1 will flip that bit. i.e. NOT(somebit) == a XOR somebit. So, in your case, just take an XOR of each bits in a and b with 1 will get you the NOT:
01100001
^ 11111111
------------
10011110
That is, we do an XOR with 11111111. Note the number of 1's is same as the number of bits in a.
Putting it together:
NOT(a) = a ^ 0b11111111
NOT(b) = b ^ 0b11111111
Now, that we got the NOTs of a and b, let's do an AND. So, what's the way to do an AND? Just do a bitwise &.
That's pretty simple:
NOT(a) AND NOT(b) == (a ^ 0b11111111) & (b ^ 0b11111111)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python - '>>' operator
There's some code that does this:
x = n - 1 >> 1
I don't know if I have to provide more syntax, but what does the >> mean? I've been searching all over, but can't find any explanation.
Its a shift right logical, it is a bitwise operation that tells the number to shift in bits by that amount. In this case you are shifting by 1, which is equivalent to dividing by 2.
If you do not understand bitwise operations, a simple conversion for you to remember would be this.
x >> n
is equivalent to
x // (2**n)
It is the bitwise shift-to-right operator.
It shifts the bits of the integer argument to the right by the number on the right-hand side of the expression:
>>> 8 >> 2
2
or illustrated in binary:
>>> bin(0b1000 >> 2)
'0b10'
Your code example is actually doubly confusing as it mixes arithmetic and bitwise operations. It should use the '//' integer division operation instead:
x = (n - 1) // 2
x >> y
is equivalent to
x.__rshift__(y)
which, as others have said, is meant to be a bitshift.
>> is the bitwise right shift operator. This operator move all bits in the first operand right by the second operand.
So: a >> b = a // 2**b
Example:
36 in binary is 0b100100
36 >> 1 is 0b10010 (last binary digit or "bit" is removed) which is 18
36 >> 2 is 0b1001 (2 bits removed) which is 9
Note that the operator goes after addition. So the code does n-1 first, then right shift it by 1 bit (i.e. divides by 2).