Here is the description:
In order to stop the Mad Coder evil genius you need to decipher the encrypted message he sent to his minions. The message contains several numbers that, when typed into a supercomputer, will launch a missile into the sky blocking out the sun, and making all the people on Earth grumpy and sad.
You figured out that some numbers have a modified single digit in their binary representation. More specifically, in the given number n the kth bit from the right was initially set to 0, but its current value might be different. It's now up to you to write a function that will change the kth bit of n back to 0.
Example
For n = 37 and k = 3, the output should be
killKthBit(n, k) = 33.
3710 = 1001012 ~> 1000012 = 3310.
For n = 37 and k = 4, the output should be
killKthBit(n, k) = 37.
The 4th bit is 0 already (looks like the Mad Coder forgot to encrypt this number), so the answer is still 37."
Here is a solution I found and I cannot understand it:
int killKthBit(int n, int k)
{
return n & ~(1 << (k - 1)) ;
}
Can someone explain what the solution does and its syntax?
Detailed explanation of your function
The expression 1 << (k - 1) shifts the number 1 exactly k-1 times to the left so as an example for an 8 Bit number and k = 4:
Before shift: 00000001
After Shift: 00010000
This marks the bit to kill. You see, 1 was shifted to the fourth position, as it was on position zero. The operator ~ negates each bit, meaning 1 becomes 0 and 0 becomes 1. For our example:
Before negation: 00010000
After negation: 11101111
At last, & executes a bit-wise AND on two operands. Let us say, we have a number n = 17, which is 00010001 in binary. Our example now is:
00010001 & 11101111 = 00000001
This is, because each bit of both numbers is compared by AND on the same position. Only positions, where both numbers have a 1 remain 1, all others are set to 0. Consequently, only position zero remains 1.
Overall your method int killKthBit(int n, int k) does exactly that with binary operators, it sets the bit on position k of number n to 0.
Here is my try
//Returns a number that has all bits same as n
// except the k'th bit which is made 0
int turnOffK(int n, int k)
{
// k must be greater than 0
if (k <= 0) return n;
// Do & of n with a number with all set bits except
// the k'th bit
return (n & ~(1 << (k - 1)));
}
Related
This question already has answers here:
Bitwise Multiply and Add in Java
(4 answers)
Closed 4 years ago.
So I have the following code to multiply two variables x and y using left and right shifts.
class Multiply {
public static long multiply(long x,long y) {
long sum = 0;
while(x != 0) {
if((x & 1) != 0) {
sum = sum+y;
}
x >>>= 1;
y <<= 1;
}
return sum;
}
public static void main(String args[]) {
long x = 7;
long y = 5;
long z = multiply(x,y);
}
}
But I dont understand the logic behind it, I understand that when you do
y<<=1
You are doubling y, but what does it mean that the number of iterations of the while loop depends on the number of bits x has?
while(x != 0)
Also why do I only sum if the rightmost bit of x is a 1?
if((x & 1) != 0) {
sum = sum+y;
}
I've really tried to understand the code but I haven't been able to get my head around the algorithm.
Those of us who remember from school how to multiply two numbers, each with two or more digits, will remember the algorithm:
23
x45
---
115
92x
----
1035
For every digit in the bottom factor, multiply it by the top factor and add the partial sums together. Note how we "shift" the partial sums (multiply them by 10) with each digit of the bottom factor.
This could apply to binary numbers as well. The thing to remember here is that no multiplication (by a factor's digit) is necessary, because it's either a 0 (don't add) or a 1 (add).
101
x110
-----
000
101
101
-----
11110
That's essentially what this algorithm does. Check the least significant bit; if it's a 1, add in the other factor (shifted), else don't add.
The line x >>>= 1; shifts right so that the next bit down becomes the least significant bit, so that the next bit can be tested during the next loop iteration. The number of loops depends on where the most significant bit 1 in x is. After the last 1 bit is shifted out of x, x is 0 and the loop terminates.
The line y <<= 1; shifts the other factor (multiplies by 2) in preparation for it be possibly added during the next loop iteration.
Overall, for every 1 bit in x at position n, it adds 2^n times y to the sum.
It does this without keeping track of n, but rather shuffling the bits x of 1 place right (dividing by 2) every iteration and shuffling the bits of y left (multiplying by 2).
Every time the 0 bit is set, which is tested by (x & 1) != 0, the amount to add is the current value of y.
Another reason this works are these equivalences:
(a + b) * y == a*y + b*y
x * y == (x/2) * (y*2)
which is the essence of what’s going on. The first equivalence allows bit-by-bit addition, and the second allows the opposite shuffling.
The >>> is an unsigned right shift which basically fills 0 irrespective of the sign of the number.
So for value x in the example 7 (in binary 111) the first time you do x >>>= 1; You are making the left most bit a zero so it changes from 111 to 011 giving you 3.
You do it again now you have 011 to 001 giving you 1
Once again and you have 001 to 000 giving you 0
So basically is giving you how many iterations before your number becomes zero. (Basically is diving your number in half and it is Integer division)
Now for the y value (5) you are adding it to your sum and then doubling the value of y
so you get:
y = 5 sum = 5
y = 10 sum = 15
y = 20 sum = 35
Only 3 iterations since x only needed to shift 3 times.
Now you have your result! 35
Look at the following sequence:
3, 5, 6, 9, 10, 12, 17, 18, 20....
All the numbers in the series has exactly 2 bits set in their binary representation. Your task is simple, you have to find the Nth number of this sequence.
1 <= T <= 105
1 <= N <= 1014
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner sc = new Scanner (System.in);
int t = sc.nextInt();
while ( t > 0 ){
int n = sc.nextInt();
t--;
int x =1;
while ( n > 0 ){
int y = 0;
while ( y < x ){
n--;
if ( n == 0 ){
System.out.println((1<<x)|(1<<y));
}
y++;
}
x++;
}
}
}
}
This is giving me a timeout error can i have an optimized solution of the given range of inputs
Examine The On-Line Encyclopedia of Integer Sequences
This is an integer sequence, which means we should be checking The On-Line Encyclopedia of Integer Sequences®. It frequently includes fairly optimal algorithms or mathematical expressions to produce elements in a specific integer sequence, so look there when you want an optimized solution.
After searching for 3, 5, 6, 9, 10, 12, 17, 18, 20, we find that this is OEIS sequence A018900, "Sum of two distinct powers of 2.", which includes several code snippets we should examine to determine which is fastest.
Fastest algorithm on OEIS page
Examining those snippets, the most efficient appears to be Smalltalk code by Hieronymus Fischer (Version 1 in the PROG section):
distinctPowersOf: b
"Version 1: Answers the n-th number of the form b^i + b^j, i>j>=0, where n is the receiver.
b > 1 (b = 2, for this sequence).
Usage: n distinctPowersOf: 2
Answer: a(n)"
| n i j |
n := self.
i := (8*n - 1) sqrtTruncated + 1 // 2.
j := n - (i*(i - 1)/2) - 1.
^(b raisedToInteger: i) + (b raisedToInteger: j)
Above code published in OEIS sequence A018900 on 20 April 2014, authored by Hieronymus Fischer, licensed by The Online Encyclopedia of Integer Sequences under the CC BY-NC 3.0 copyright license.
Appropriate data type
Signed 64-bit longs run out of space to hold the result and can begin to set incorrect bits after n exceeds 1,953. Since n won't exceed 1,014 in practice, long results will be fine.
Signed 32-bit ints run out of space after n exceeds 465, so they aren't large enough.
Solution using optimized algorithm
Here, we translate the Smalltalk algorithm to Java. Since optimized efficiency is your goal, we'll speed things up very slightly by using << 3 to multiply a small int value by eight and >>> 1 to perform floored division by two on a positive int:
import java.util.Scanner;
public class Solution {
// Gives the exact floor of the square root of x.
// based on Java algorithm by Programmer Olathe
// from http://www.codecodex.com/wiki/Calculate_an_integer_square_root#Java
public static final int floorSqrt(final int x) {
return (int) Math.sqrt(x);
} // Finds the nᵗʰ integer with exactly two bits set.
// Cannot properly handle n > 1953.
// based on Smalltalk algorithm by Hieronymus Fischer
// from https://oeis.org/A018900
public static final long nthWithTwoBitsSet(final int n) {
// Find the indexes of the two bits.
final int i = (floorSqrt((n << 3) - 1) + 1) >>> 1;
final int j = n - ((i*(i - 1)) >>> 1) - 1; // Return a long with the two bits set.
return (1L << i) | (1L << j);
} public static final void main(final String[] args) {
final Scanner in = new Scanner(System.in);
for (int t = in.nextInt(); t > 0; t--) {
System.out.println(nthWithTwoBitsSet(in.nextInt()));
}
}
}
Solution with slightly improved efficiency
We can gain further efficiency at the cost of bad design by combining all three methods into one:
import java.util.Scanner;
public class Solution {
// Cannot properly handle n > 1953.
// based on Java floored-square-root algorithm by Programmer Olathe
// from http://www.codecodex.com/wiki/Calculate_an_integer_square_root#Java
// based on Smalltalk nᵗʰ-with-two-bits-set algorithm by Hieronymus Fischer
// from https://oeis.org/A018900
public static final void main(final String[] args) {
final Scanner in = new Scanner(System.in);
for (int t = in.nextInt(); t > 0; t--) {
final int n = in.nextInt(); // Find the indexes of the two bits.
final int i = (((int) Math.sqrt((n << 3) - 1)) + 1) >>> 1;
final int j = n - ((i*(i - 1)) >>> 1) - 1; // Print a long with the two bits set.
System.out.println((1L << i) | (1L << j));
}
}
}
For my explanation I number the bit position from the least significant bit from 0. So 3 has bits 0 and 1 set. 5 has bits 0 and 2 set, etc.
There are 0 numbers where the most significant set bit is bit 0 (because then there is no other bit to set). 1 number where it’s bit 1 (3). Two numbers where it’s bit 2 (101 = 5 and 110 = 6). And so forth. m numbers where the most significant set bit is bit m.
This in turn means that up to and including numbers where bit b is the more significant of the two set bits, there are b * (b + 1) / 2 numbers. Let’s for a moment assume this is equal to N. Then according to the formual for solving a quadratic equation b = (sqrt(8 * N + 1) - 1) / 2. If this isn’t a whole number, it’s because N didn’t exactly equal the formula I said. Round up to find b and then find which other bit must be set for everything to agree.
I am on purpose not giving you the full solution. You wanted to solve this problem, you do the work. I hope my input is useful.
The other — smaller but easier — optimization is: Find the largest N among the test cases. Calculate the numbers of the sequence up to this largest N and put them into an array (you may modify your code from the question to do this). Then print all the required results by looking them up in the array. Language nitpicking: One may may argue that this is not literally an optimization since this word comes from latin optimus meaning best and it doesn’t produce the fastest possible program.
I hava see this code in HashMap:
/**
* Returns index for hash code h.
*/
static int indexFor(int h, int length) {
// assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
return h & (length-1);
}
The HashMap has this document:
when length is a power of two then h & (length-1) is equals h%length
I want to know the principle in math
just is why h & (length-1) == h%length (length is a power of two)
First you can think what it looks like when you take any integer n mod power of 2.
WLOG let this power of 2 is 10000 in binary (indeed it must be of the form 100...0), what does its multiples looks like? Its multiples must look like...whatever digit...0000. The last 4 digit must be zero.
So what is a number n mod 10000? Let this number n be ...whatever digit...1011. This number can be expressed as ...whatever digit...0000 + 1011, now it is obvious that n mod 10000 indeed only the last 4 digits is left.
In general, let length be a power of 2 which has x zeros, then n%length is the least x significant digits of n
So legnth - 1is indeed 111..111 (x digit 1), and when you take bitwise and with the number n, the least x significant digits of n is preserved and returned, which is what we want. Using the same example above,
Length = 10000, Length - 1 = 1111
n = 101001101 = 101000000 + 1101
=> n % Length = 1101
n & (Length - 1) = 1101
= n % Length
Just imagine: any power of two contains single bit set and has binary representation like this:
l = 00010000
if you subtract 1, it will contain ones at the right places
m = l-1 = 00001111
binary AND operation with any h makes all most significant bits zero, leaving less significant ones
10101010 & 00001111 = 00001010
This is equivalent to modulo operation with modulo l
Question is based on this site.
Could someone explain the meaning of these lines:
private int getBitValue(int n, int location) {
int v = n & (int) Math.round(Math.pow(2, location));
return v==0?0:1;
}
and
private int setBitValue(int n, int location, int bit) {
int toggle = (int) Math.pow(2, location), bv = getBitValue(n, location);
if(bv == bit)
return n;
if(bv == 0 && bit == 1)
n |= toggle;
else if(bv == 1 && bit == 0)
n ^= toggle;
return n;
}
int v = n & (int) Math.round(Math.pow(2, location));
Math.pow(2, location) raises 2 to the given power. This is rounded and converted to an integer. In binary, this will be 00000001 if location==0, 00000010 if location==1, 00000100 if location==2, etc. (Much better would be 1 << location which shifts a "1" by a certain number of bits, filling in 0 bits at the right. Using Math.pow will probably try to compute the logarithm of 2 every time it's called.)
n & ... is a bitwise AND. Since the item on the right has just one bit set, the effect is to zero out every bit in n except for that one bit, and put the result in v. This means that v will be 0 if that one bit is 0 in n, and something other than 0 if that bit is `, which means
return v==0?0:1;
returns 0 if the bit is clear and 1 if it's set.
int toggle = (int) Math.pow(2, location), bv = getBitValue(n, location);
toggle is set to that Math.pow thing I already described. bv is set to the bit that's already in n, which is 0 or 1. If this equals the thing you're setting it to, then we don't need to do anything to n:
if(bv == bit)
return n;
Otherwise, either we need to set it to 1 (remember that toggle will have just one bit set). n |= toggle is the same as n = n | toggle. | is a bit-wise OR, so that one bit will be set in n and all other bits in n will remain the same"
if(bv == 0 && bit == 1)
n |= toggle;
Or we need to set the bit to 0. n ^= toggle is the same as n = n ^ toggle. n is an exclusive OR. If we get here, then the bit in n is 1, and the bit in toggle is 1, and we want to set the bit in n to 0, so exclusive OR will change that bit to 0 while leaving every other bit the same:
else if(bv == 1 && bit == 0)
n ^= toggle;
The getBitValue just gets the value of a specified bit (on a certain location)
The setBitValue sets the value of a bit on the matched specific location.
These getter/setter methods are usually used for image processing, i.e. if you have a musk and you want to change a specific bit value.
Nothing more or less.
I need to find the largest power of 2 less than the given number.
And I stuck and can't find any solution.
Code:
public class MathPow {
public int largestPowerOf2 (int n) {
int res = 2;
while (res < n) {
res =(int) Math.pow(res, 2);
}
return res;
}
}
This doesn't work correctly.
Testing output:
Arguments Actual Expected
-------------------------
9 16 8
100 256 64
1000 65536 512
64 256 32
How to solve this issue?
Integer.highestOneBit(n-1);
For n <= 1 the question doesn't really make sense. What to do in that range is left to the interested reader.
The's a good collection of bit twiddling algorithms in Hacker's Delight.
Change res =(int)Math.pow(res, 2); to res *= 2; This will return the next power of 2 greater than res.
The final result you are looking for will therefore finally be res / 2 after the while has ended.
To prevent the code from overflowing the int value space you should/could change the type of res to double/long, anything that can hold higher values than int. In the end you would have to cast one time.
You can use this bit hack:
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
v >>= 1;
Why not use logs?
public int largestPowerOf2(int n) {
return (int)Math.pow(2, Math.floor(Math.log(n) / Math.log(2));
}
log(n) / log(2) tells you the number of times 2 goes into a number. By taking the floor of it, gets you the integer value rounding down.
There's a nice function in Integer that is helpful, numberOfLeadingZeros.
With it you can do
0x80000000 >>> Integer.numberOfLeadingZeros(n - 1);
Which does weird things when n is 0 or 1, but for those inputs there is no well-defined "highest power of two less than n".
edit: this answer is even better
You could eliminate the least significant bit in n until n is a power of 2. You could use the bitwise operator AND with n and n-1, which would eliminate the least significant bit in n until n would be a power of 2. If originally n would be a power of 2 then all you would have to do is reduce n by 1.
public class MathPow{
public int largestPowerOf2(int n){
if((n & n-1) == 0){ //this checks if n is a power of 2
n--; //Since n is a power of 2 we have to subtract 1
}
while((n & n-1) != 0){ //the while will keep on going until n is a power of 2, in which case n will only have 1 bit on which is the maximum power of 2 less than n. You could eliminate the != 0 but just for clarity I left it in
n = n & n-1; //we will then perform the bitwise operation AND with n and n-1 to eliminate the least significant bit of n
}
return n;
}
}
EXPLANATION:
When you have a number n (that is not a power of 2), the largest power of 2 that is less than n is always the most significant bit in n. In case of a number n that is a power of 2, the largest power of 2 less than n is the bit right before the only bit that is on in n.
For example if we had 8 (which is 2 to the 3rd power), its binary representation is 1000 the 0 that is bold would be the largest power of 2 before n. Since we know that each digit in binary represents a power of 2, then if we have n as a number that's a power of 2, the greatest power of 2 less than n would be the power of 2 before it, which would be the bit before the only bit on in n.
With a number n, that is not a power of 2 and is not 0, we know that in the binary representation n would have various bits on, these bits would only represent a sum of various powers of 2, the most important of which would be the most significant bit. Then we could deduce that n is only the most significant bit plus some other bits. Since n is represented in a certain length of bits and the most significant bit is the highest power of 2 we can represent with that number of bits, but it is also the lowest number we can represent with that many bits, then we can conclude that the most significant bit is the highest power of 2 lower than n, because if we add another bit to represent the next power of 2 we will have a power of 2 greater than n.
EXAMPLES:
For example, if we had 168 (which is 10101000 in binary) the while would take 168 and subtract 1 which is 167 (which is 10100111 in binary). Then we would do the bitwise AND on both numbers.
Example:
10101000
& 10100111
------------
10100000
We now have the binary number 10100000. If we subtract 1 from it and we use the bitwise AND on both numbers we get 10000000 which is 128, which is 2 to the power of 7.
Example:
10100000
& 10011111
-------------
10000000
If n were to be originally a power of 2 then we have to subtract 1 from n. For example if n was 16, which is 10000 in binary, we would subtract 1 which would leave us with 15, which is 1111 in binary, and we store it in n (which is what the if does). We then go into the while which does the bitwise operator AND with n and n-1, which would be 15 (in binary 1111) & 14 (in binary 1110).
Example:
1111
& 1110
--------
1110
Now we are left with 14. We then perform the bitwise AND with n and n-1, which is 14 (binary 1110) & 13 (binary 1101).
Example:
1110
& 1101
---------
1100
Now we have 12 and we only need to eliminate one last least significant bit. Again, we then execute the bitwise AND on n and n-1, which is 12 (in binary 1100) and 11 (in binary 1011).
Example
1100
& 1011
--------
1000
We are finally left with 8 which is the greatest power of 2 less than 16.
You are squaring res each time, meaning you calculate 2^2^2^2 instead of 2^k.
Change your evaluation to following:
int res = 2;
while (res * 2 < n) {
res *= 2;
}
Update:
Of course, you need to check for overflow of int, in that case checking
while (res <= (n - 1) / 2)
seems much better.
Here is a recursive bit-shifting method I wrote for this purpose:
public static int nextPowDown(int x, int z) {
if (x == 1)
return z;
return nextPowDown(x >> 1, z << 1);
}
Or shorter definition:
public static int nextPowTailRec(int x) {
return x <= 2 ? x : nextPowTailRec(x >> 1) << 1;
}
So in your main method let the z argument always equal 1. It's a pity default parameters aren't available here:
System.out.println(nextPowDown(60, 1)); // prints 32
System.out.println(nextPowDown(24412, 1)); // prints 16384
System.out.println(nextPowDown(Integer.MAX_VALUE, 1)); // prints 1073741824
A bit late but...
(Assuming 32 bit number.)
n|=(n>>1);
n|=(n>>2);
n|=(n>>4);
n|=(n>>8);
n|=(n>>16);
n=n^(n>>1);
Explanation:
The first | makes sure the original top bit and the 2nd highest top bit are set. The second | makes sure those two, and the next two are, etc, until you potentially hit all 32 bits. Ie
100010101 -> 111111111
Then we remove all but the top bit by xor'ing the string of 1's with that string of 1's shifted one to the left, and we end up with just the one top bit followed by 0's.
public class MathPow {
public int largestPowerOf2 (int n) {
int res = 2;
while (res < n) {
res = res * 2;
}
return res;
}
}
Find the first set bit from left to right and make all other set bits 0s.
If there is only 1 set bit then shift right by one.
I think this is the simplest way to do it.
Integer.highestOneBit(n-1);
public class MathPow
{
public int largestPowerOf2(int n)
{
int res = 1;
while (res <= (n-1)/2)
{
res = res * 2;
}
return res;
}
}
If the number is an integer you can always change it to binary then find out the number of digits.
n = (x>>>0).toString(2).length-1
p=2;
while(p<=n)
{
p=2*p;
}
p=p/2;
If the number is a power of two then the answer is obvious. (just bit shift) if not well then it is also can be achieved by bit shifting.
find the length of the given number in binary representation. (13 in binary = 1101 ; length is 4)
then
shift 2 by (4-2) // 4 is the length of the given number in binary
the below java code will solve this for BigIntegers(so basically for all numbers).
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String num = br.readLine();
BigInteger in = new BigInteger(num);
String temp = in.toString(2);
System.out.println(new BigInteger("2").shiftLeft(temp.length() - 2));
I saw another BigInteger solution above, but that is actually quite slow. A more effective way if we are to go beyond integer and long is
BigInteger nvalue = TWO.pow(BigIntegerMath.log2(value, RoundingMode.FLOOR));
where TWO is simply BigInteger.valueOf(2L)
and BigIntegerMath is taken from Guava.
Simple bit operations should work
public long largestPowerOf2 (long n)
{
//check already power of two? if yes simply left shift
if((num &(num-1))==0){
return num>>1;
}
// assuming long can take 64 bits
for(int bits = 63; bits >= 0; bits--) {
if((num & (1<<bits)) != 0){
return (1<<bits);
}
}
// unable to find any power of 2
return 0;
}
/**
* Find the number of bits for a given number. Let it be 'k'.
* So the answer will be 2^k.
*/
public class Problem010 {
public static void highestPowerOf2(int n) {
System.out.print("The highest power of 2 less than or equal to " + n + " is ");
int k = 0;
while(n != 0) {
n = n / 2;
k++;
}
System.out.println(Math.pow(2, k - 1) + "\n");
}
public static void main(String[] args) {
highestPowerOf2(10);
highestPowerOf2(19);
highestPowerOf2(32);
}
}
if(number>=2){
while(result < number){
result *=2;
}
result = result/ 2;
System.out.println(result);
}