Given a long int x, count the number of values of a that satisfy the following conditions:
a XOR x > x
0 < a < x
where a and x are long integers and XOR is the bitwise XOR operator
How would you go about completing this problem?
I should also mentioned that the input x can be as large as 10^10
I have managed to get a brute force solution by iterating over 0 to x checking the conditions and incrementing a count value.. however this is not an optimal solution...
This is the brute force that I tried. It works but is extremely slow for large values of x.
for(int i =0; i < x; i++)
{
if((0 < i && i < x) && (i ^ x) > x)
count++;
}
long long NumberOfA(long long x)
{
long long t = x <<1;
while(t^(t&-t)) t ^= (t&-t);
return t-++x;
}
long long x = 10000000000;
printf("%lld ==> %lld\n", 10LL, NumberOfA(10LL) );
printf("%lld ==> %lld\n", x, NumberOfA(x) );
Output
10 ==> 5
10000000000 ==> 7179869183
Link to IDEOne Code
Trying to explain the logic (using example 10, or 1010b)
Shift x to the left 1. (Value 20 or 10100b)
Turn off all low bits, leaving just the high bit (Value 16 or 10000b)
Subtract x+1 (16 - 11 == 5)
Attempting to explain
(although its not easy)
Your rule is that a ^ x must be bigger than x, but that you cannot add extra bits to a or x.
(If you start with a 4-bit value, you can only use 4-bits)
The biggest possible value for a number in N-bits is 2^n -1.
(eg. 4-bit number, 2^4-1 == 15)
Lets call this number B.
Between your value x and B (inclusive), there are B-x possible values.
(back to my example, 10. Between 15 and 10, there are 5 possible values: 11, 12, 13, 14, 15)
In my code, t is x << 1, then with all the low bits turned off.
(10 << 1 is 20; turn off all the low bits to get 16)
Then 16 - 1 is B, and B - x is your answer:
(t - 1 - x, is the same as t - ++x, is the answer)
One way to look at this is to consider each bit in x.
If it's 1, then flipping it will yield a smaller number.
If it's 0, then flipping it will yield a larger number, and we should count it - and also all the combinations of bits to the right. That conveniently adds up to the mask value.
long f(long const x)
{
// only positive x can have non-zero result
if (x <= 0) return 0;
long count = 0;
// Iterate from LSB to MSB
for (long mask = 1; mask < x; mask <<= 1)
count += x & mask
? 0
: mask;
return count;
}
We might suspect a pattern here - it looks like we're just copying x and flipping its bits.
Let's confirm, using a minimal test program:
#include <cstdlib>
#include <iostream>
int main(int, char **argv)
{
while (*++argv)
std::cout << *argv << " -> " << f(std::atol(*argv)) << std::endl;
}
0 -> 0
1 -> 0
2 -> 1
3 -> 0
4 -> 3
5 -> 2
6 -> 1
7 -> 0
8 -> 7
9 -> 6
10 -> 5
11 -> 4
12 -> 3
13 -> 2
14 -> 1
15 -> 0
So all we have to do is 'smear' the value so that all the zero bits after the most-significant 1 are set, then xor with that:
long f(long const x)
{
if (x <= 0) return 0;
long mask = x;
while (mask & (mask+1))
mask |= mask+1;
return mask ^ x;
}
This is much faster, and still O(log n).
Related
I want to be able to retain the same amount of bits to my vector whilst still performing binary addition. For example.
int numOfBits = 4;
int myVecVal = 3;
vector< bool > myVec;
GetBinaryVector(&myVec,myVecVal, numOfBits);
and its output would be:
{0, 0, 1, 1}
I don't know how to make a function of GetBinaryVector though, any ideas?
This seems to work (although the article I added in initial comment seem to suggest you only have byte level access):
void GetBinaryVector(vector<bool> *v, int val, int bits) {
v->resize(bits);
for(int i = 0; i < bits; i++) {
(*v)[bits - 1 - i] = (val >> i) & 0x1;
}
}
The left hand side sets the i'th least significant bit which is index bits - 1 - i. The right hand side isolates the i'th least significant bit by bit shifting the value down i'th bit and masking everything but the least significant bit.
In your example val = 8, bits = 15. In the first iteration i = 0: we have (*v)[15 - 1 - 0] = (8 >> 0) & 0x1. 8 is binary 1000 and shifting it down 0 is 1000. 1000 & 0x1 is 0. Let's jump to i = 4: (*v)[15 - 1 - 4] = (8 >> 4) & 0x1. 1000 >> 4 is 1 and 1 & 0x1 is 1, so we set (*v)[10] = 1. The resulting vector is { 0, ..., 0, 1, 0, 0, 0 }
Can anyone help me in understanding the following code:-
int r, countIt(int n) {
while (r += " 2 "[n % 10] & 3, n /= 10);
return r;
}
I found this code in one of the challenges of codefights.com, https://codefights.com/challenge/v5Zg8trjoun3PTxrZ/solutions/Aj3ppbhSShixt4nBi
This is a solution for counting number of holes in a number.
e.g.
1111 = 0
0000 = 4
1234 = 0
8888 = 8
I am not able to understand the following things:
1. Logic of this code
2. comma (,) operator used in return data type of the function
3. Use of []operator after string.
4. And actually the whole code.
Is that some kind of obfuscated C contest submission? Or code golf?
First, the weird declaration. It's just combining two unrelated declarations on one line. Just as
int x, y;
is equivalent to
int x;
int y;
so is your code equivalent to
int r;
int countIt(int n) {...}
It's a little known and, thankfully, little used quirk of the C grammar that you can do that.
The loop would become clearer if written this way:
do {
r += " 2 "[n % 10] & 3;
n /= 10;
} while (n);
It basically iterates over digits in the decimal representation of n.
Now the part of r += " 2 "[n % 10] & 3;. n % 10 is the low-order decimal digit of n. We use that as an index into a string literal (which is just an array of chars), then extract two low-order bits of the character's ASCII code and discard the rest. I'm pretty sure that, in the original program you copied this code from, the characters in that literal were not spaces, but rather certain unprintable characters chosen in such a way that the two low-order bits of their ASCII codes gave precisely the number of "holes" in the corresponding digit. 2 character is a red-herring - it's in position 12, but only characters 0 through 9 are actually used.
In other words, this part can be more clearly written this way:
static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1};
int digit = n % 10;
r += numHoles[digit];
Put together, we have:
int countIt(int n) {
// number of holes in digit 0 1 2 3 4 5 6 7 8 9
static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1};
int r = 0;
do {
int digit = n % 10;
r += numHoles[digit];
n /= 10;
} while (n);
return r;
};
I looked up the link you provided. After carefully observing the code i came to following conclusion.
int r, countIt(int n) {.....}
is equivalent to writing as
int r;
int countIt(int n){.....}
now for
while (r += " 2 "[n % 10] & 3, n /= 10);
is equivalent to:
do{
r += " 2 "[n % 10] & 3;
n/=10;
}while(n);
Now comes the logical part of the code
r += " 2 "[n % 10] & 3;
let me give you some basics.
In c++
cout<<"abcde"[2];
will give you output
c
now if you watch carefully the code in link which you provided
its something like this:
r += " 2 "[n % 10] & 3;
is nothing but
r += "TAB,SPACE,SPACE,SPACE,SPACE,SPACE,TAB,SPACE,2,TAB"[n % 10] & 3;
Now its time to explain how this code is calculating number of holes.
The ASCII value of TAB is 9 whose binary equivalent is 1001.
The ASCII value of SPACE is 32 whose binary equivalent is 100000.
so bit wise anding TAB with 3 will result
1001 & 0011 = 0001 which is 1
bit wise anding SPACE with 3 will result
100000 & 000011 = 000000 which is 0
replacing TABs with 1 and SPACEs with 0 hence this concludes as writing
do{
r += "1000001021"[n % 10] & 3;
n/=10;
}while(n);
n % 10 is the low-order decimal digit of n. We use that as an index into a string literal, which contains information about how many holes is there in that low-order decimal digit then add it to result r.
Using special chars in browsers can be a problem, from Ascii Table we can use all chars that in octal ends in 0 to 2 or 4 to 6, using those 2 bits to know how many holes the number have (% 3 is the same as % 0b11, an and with the last 2 bits).
One solution with ascii chars is:
int countIt(int n) {
int r;
while (r += "1000101021"[n % 10] & 3, n /= 10);
return r;
}
Instead of "0" to "2", i could use something like this:
int countIt(int n) {
int r;
while (r += "! X0) I#*9"[n % 10] & 3, n /= 10);
return r;
}
I don't know what chars he tried to use, but didn't work in the challenge website.
Suppose X and Y are two positive integers and Y is a power of two. Then what does this expression calculate?
(X+Y-1) & ~(Y-1)
I found this expression appearing in certain c/c++ implementation of Memory Pool (X represents the object size in bytes and Y represents the alignment in bytes, the expression returns the block size in bytes fit for use in the Memory Pool).
&~(Y-1) where Y is a power of 2, zeroes the last n bits, where Y = 2n: Y-1 produces n 1-bits, inverting that via ~ gives you a mask with n zeroes at the end, anding via bit-level & zeroes the bits where the mask is zero.
Effectively that produces a number that is some multiple of Y's power of 2.
It can maximally have the effect of subtracting Y-1 from the number, so add that first, giving (X+Y-1) & ~(Y-1). This is a number that's not less than X, and is a multiple of Y.
It gives you the next Y-aligned address of current address X.
Say, your current address X is 0x10000, and your alignment is 0x100, it will give you 0x10000. But if your current address X is 0x10001, you will get "next" aligned address of 0x10100.
This is useful in the scenario that you want your new object always to be aligned to blocks in memory, but not leaving any block unused. So you want to know what is the next available block-aligned address.
Why don't you just try some input and observe what happens?
#include <iostream>
unsigned compute(unsigned x, unsigned y)
{
return (x + y - 1) & ~(y - 1);
}
int main()
{
std::cout << "(x + y - 1) & ~(y - 1)" << std::endl;
for (unsigned x = 0; x < 9; ++x)
{
std::cout << "x=" << x << ", y=2 -> " << compute(x, 2) << std::endl;
}
std::cout << "----" << std::endl;
std::cout << "(x + y - 1) & ~(y - 1)" << std::endl;
for (unsigned x = 0; x < 9; ++x)
{
std::cout << "(x=" << x << ", y=2) -> " << compute(x, 2) << std::endl;
}
return 0;
}
Live Example
Output:
First set uses x in [0, 8] and y is constant 2. Second set uses x in [0, 8] and y is constant 4.
(x + y - 1) & ~(y - 1)
x=0, y=2 -> 0
x=1, y=2 -> 2
x=2, y=2 -> 2
x=3, y=2 -> 4
x=4, y=2 -> 4
x=5, y=2 -> 6
x=6, y=2 -> 6
x=7, y=2 -> 8
x=8, y=2 -> 8
----
(x + y - 1) & ~(y - 1)
(x=0, y=2) -> 0
(x=1, y=2) -> 2
(x=2, y=2) -> 2
(x=3, y=2) -> 4
(x=4, y=2) -> 4
(x=5, y=2) -> 6
(x=6, y=2) -> 6
(x=7, y=2) -> 8
(x=8, y=2) -> 8
It's easy to see the output (i.e., result right of ->) is always a multiple of y such that the output is greater than or equal to x.
First I assume that X and Y are unsigned integers.
Let's have a look at the right part:
If Y is a power of 2, it is represented in binary by one bit to 1 and all the others to 0. Example 8 will be binary 00..01000.
If you substract 1 the highest bit will be 0 and all the bits to its right will become 1. Example 8-1= 7 and in binary 00..00111
If you ~ negate this number you will make sure that all highest bit (including the original one will turn to 1 and the lovest to 0. Example: ~7 will be 11..11000
Now if you do a binary AND (&) with any number, you will set to 0 all the lower bits, in our example, the 3 lower bits. THe resulting number is hence a multiple of Y.
Let's look at the left side:
We've already analysed Y-1. In our example we had 7, that is 00..00111
If you add this to any number, you make sure that the result is greater than or equal to Y. Example with 5: 5+7=12 so 00..01100 and example with 10: 10+7=17 so 00..10001
If you then perform the AND, you'll erase the lower bits. so in our example with 5, we come to 00..01000 = 8 and in our example with 10 we get 00..10000 16.
Conclusion, it's the smallest multiple of Y wich is greater or equal to X.
Let's break it down, piece by piece.
(X+Y-1) & ~(Y-1)
Let's suppose that X = 11 and Y = 16 in accordance with your rules and that the integers are 8 bits.
(11+16-1) & ~(16-1)
Do the Addition and Subtraction
(26) & ~(15)
Translate this into binary
(0001 1010) & ~(0000 1111)
~ means not or to invert the zeros and ones
(0001 1010) & (1111 0000)
& means only to take the bits that are both ones
0001 0000
convert back to decimal
16
other examples
X = 78, Y = 32 results in 96
X = 25, Y = 64 results in 64
X = 47, Y = 16 results in 48
So, it would seem to me that the purpose of this is to find lowest multiple of Y that is equal to or greater than X. This could be used for finding the start/end address of a block of memory, or it could be used for positioning items on the screen, or any number of other possible answers as well. But without context and possibly even a full code example. There's no guarantee.
(X+Y-1) & ~(Y-1)
x = 7 = 0b0111
y = 4 = 0b0100
x+y-1 = 0b1010
y-1 = 3 = 0b0011
~(y-1) = 0b1100
(x+y-1) & ~(y-1) = 0b1000 = 8
--
x = 12 = 0b1100
y = 2 = 0b0010
x+y-1 = 13 = 0b1101
y-1 = 1 = 0b0001
~(y-1) = 0b1110
(x+y-1) & ~(y-1) = 0b1100 = 12
(x+y-1) & ~(y-1) is the smallest multiple of y greater than or equal to x
It seems provides a specified alignment of a value for example of a memory address (for example when you want to get the next aligned address).
For example if you want that a memory address would be aligned at the paragraph bound you can write
( address + 16 - 1 ) & ~( 16 - 1 )
or
( address + 15 ) & ~15
or
( address + 15 ) & ~0xf
In this case all bits before 16 will be zeroed.
This part of expression
( address + alignment - )
is used for rounding.
and this part of expression
~( alignment - 1 )
is used to build a mask thet zeroes low bits.
How is this code working for multiple of 5
bool isMultipleof5(int n)
{
/* If n is a multiple of 5 then we make sure that last
digit of n is 0 */
if ( (n&1) == 1 )
n <<= 1;
float x = n;
x = ( (int)(x*0.1) )*10;
/* If last digit of n is 0 then n will be equal to (int)x */
if ( (int)x == n )
return true;
return false;
}
It first makes n divisable by 2.
Next, it checks if it is divisable by 10 by multiplying with 0.1 and again with 10. The idea that if it is divisable by 10, you will get back to the original, and only then.
So, if the modifies n is divisable by 10 - it is certainly divisable by 5 as well, and since modified n is always divisable by 2, if it is divisable by 5 it will be divisable by 10, and the algorithm works.
NOTE: This is very unsuggested and especially might break with large values due to floating point precision issues. using the % operator should be prefered: return (n % 5) == 0
This is how the code works with some examples.
if ( (n&1) == 1 ) //Checks if the number is odd
n <<= 1; //Multiplies the number by 2 if odd
x = ( (int)(x * 0.1) //Divides the number 10 then truncates any decimal places
* 10 ) //Multiplies it back by 10
if ( (int)x == n ) //If the floating point value equals the (semi) original value its divisible by 5
return true;
return false; //Other wise false
Example:
15 & 1 == 1 //15 is odd
15 <<= 1; //n is now 30
30 / 10 = 3;
3 * 10 = 30; //x is now 30
30 == 30 //15 is a multiple of 5
17 & 1 == 1 //17 is odd
17 <<= 1; //n is now 34
34 / 10 = 3.4;
((int)3.4 = 3) * 10 = 30; //x is now 30
30 != 34 //17 is not a multiple of 5.
As others said though just simply use the mod operator %.
This is how it works:
Double the number. Now anything ending in 5 will be divisible 10 (and also divisible by 5). n <<= 1; (the check for oddness is unnecessary (n&1) == 1)
Divide it by 10, and cast away the fractional part. (int)(x*0.1)
Multiply it by 10, so now we have the same number as in step 1 only if the number in step 1 was already divisible by 10.
The use of floating point to divide by 10 makes this algorithm dangerous and probably incorrect for large values.
Try this
bool isMultipleof5(int n)
{
return (n%5) == 0;
}
A simpler way would be
bool isMultipleof5(int n)
{
return 0 == ( n % 5 ) ;
}
#define IS_MULTIPLE_OF_5(n) (((n)%5) ? 0 : 1)
I'd agree that (n % 5) == 0 would be an ideal solution, but that wasn't really the question.
This code works because it first checks if the input is odd. If it is, it multiplies by two. Since all odd multiples of 5 end with a 5, multiplying by 2 gives a number that ends with 0.
Then it checks if the last digit is 0. This can only happen if it started as a 0 (i.e. was even, we didn't change it) or if it was odd and ended in a 5 (we multiplied by 2). So, if it ends in 0 then the input must have been divisible by 5.
I'd add that this is also an awkward way to check the value of the last digit. I'd suggest n % 10 == 0 instead, but like others mentioned... you could have just used n % 5 == 0 in the first place ;).
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
How do you set, clear and toggle a single bit in C?
Removing lowest order bit
n is a positive integer. How can its rightmost set bit be unset?
Say n= 7 => n = 0111.
I want 0110 as the output. Is there any simple bitwise hack to achieve the goal?
Try n & (n-1) where & is bitwise AND
n = 7
n - 1 =6
n & (n-1)=> 0 1 1 1 (7)
& 0 1 1 0 (6)
---------
0 1 1 0 (done!)
EDIT (in response to the comment given by Forest)
n = 6
n - 1 = 5
n & (n-1)=> 0 1 1 0 (6)
& 0 1 0 1 (5)
---------
0 1 0 0 (done!)
Your question is unclear.
If you just want to unset bit 0, here are some methods (with slight variations in behavior depending on your types involved):
x &= -2;
x &= ~1;
x -= (x&1);
If you want to unset the lowest bit among the bits that are set, here are some ways:
x &= x-1;
x -= (x&-x);
Note that x&-x is equal to the lowest bit of x, at least when x is unsigned or twos complement. If you want to do any bit arithmetic like this, you should use only unsigned types, since signed types have implementation-defined behavior under bitwise operations.
unsigned int clr_rm_set_bit(unsigned int n)
{
unsigned int mask = 1;
while(n & mask) {
mask <<= 1;
}
return n & ~mask;
}