Permutation and combination required - java

I am trying to read the "day" value from native calendar of blackberry,the value is returned as a integer ,which is mapped to a value for each day of the week.The values are like :
Monday:32768
tue: 16384
wed :8192
thur :4096
fri :2048
sat :1024
sun :65536
I am able to see if the value is mon/tue/wed/thu/fri/sat/sun if the event is occuring for a single day using
if (rule.MONDAY == rule.getInt(rule.DAY_IN_WEEK)) {
System.out.println("occurs monday");
}
rule.getInt(rule.DAY_IN_WEEK)
value is also same as monday value.
Now the issue is, if the events is occuring on two/three or more number of days then
rule.getInt(rule.DAY_IN_WEEK)
returns me a sum of all days selected.
EXAMPLE: if the days are :wed,sat then i get the result as 9216 ,sum of wed+sat ,from this i am not getting to know which are the days the event occurs.
How can i do a permutation/combination of these numbers and get the exact result for 'n' number of days selected.

I assume the days are just bit flags in a number so you might change your check:
if ( (rule.getInt(rule.DAY_IN_WEEK) & rule.MONDAY) != 0 ) {
System.out.println("occurs monday");
}

Use binary and operator like this:
int day = rule.getInt(rule.DAY_IN_WEEK)
if(day & rule.MONDAY != 0) {
System.out.println("occurs monday");
}
if(day & rule.WEDNESDAY != 0) {
System.out.println("occurs wednesday");
} /* and so on */
Notice that:
0000 0100 0000 0000 = 1024
0000 1000 0000 0000 = 2048
.
.
.
check also bit mask

To know which days of the week the event occurs, you need to do something like this:
boolean occursOnMonday = (rule.getInt(rule.DAY_IN_WEEK) & rule.MONDAY) != 0;
where & is the bitwise AND operator. Why is this so?
Wednesday is 8192, which in binary it is 10000000000000 (2 times 13)
Saturday is 1024, which in binary it is 00010000000000 (2 times 9)
So an event that happens on Wed and Sat is 9216, which is 10010000000000.
Then using bit operations you are able to know what bits are in 1 and what bits are in 0, and with that you know what days the event happens.

Related

Finding odd/even numbers

I have been given this sample code for some exercises, and it shows how to find whether an integer is odd or even.
int x = 4;
if ( (x & 1) == 0 )
{
System.out.println("even");
}
else
{
System.out.println("odd");
}
But I dont understand why you do ' x & 1 '. What's the purpose of that?
In the binary representation of a number, any number with its least significant bit set to 0 is even. It would also be helpful to know what the & operator does.
For example 5 = 0101 (binary) and 1 = 0001 (binary). In this case, it compares 0101 with 0001.
You compare it bitwise, so the first bit would be 1 & 0 = 0. The second bit is 0 & 0 = 0. The third bit is 0 & 0 = 0. The last bit is 1 & 1 = 1.
So 5 & 1 = 0001, which is 1 in decimal. 1 == 0 evaluates to false for x = 5.
For all other even numbers, the least significant digit is 0, so any even number & 1 will always evaluate to 0.
That is because & performs a bitwise AND operation:
if ( (x & 1) == 0 )
Your code is as good as saying, print "Odd" if last binary digit of x is 1.
And it will work because all odd numbers will always have 1 as their last binary digit.
Consider this:
1 is 0001 in binary.
2 is 0010 in binary.
When (0001 & 0010) only those positions with both matched with 1 will remained as 1, which means:
0001 & 0010 gives you 0000 (0) // 1 & 2 = 0
Look at this pattern:
0001 & 0001 = 1 //1 & 1 = 1 (is odd)
0010 & 0001 = 0 //2 & 1 = 0 (is even)
0011 & 0001 = 1 //3 & 1 = 1 (is odd)
0100 & 0001 = 0 //4 & 1 = 0 (is even)
0101 & 0001 = 1 //5 & 1 = 1 (is odd)
0110 & 0001 = 0 //6 & 1 = 0 (is even)
It's a bitwise AND operation between the binary representation of the two numbers. Odd numbers always have their 1 bit set. Even numbers do not.
So, the ampersand AND == 0 is true for even numbers, but not for odd ones.
http://www.tutorialspoint.com/java/java_bitwise_operators_examples.htm
It evaluates the variable's binary value
Let's say x = 6 (110 in binary) and y = 7 (111)
Since we know that 1&0=0 and 1&1=1 (or true&false=false and true&true=true)
x & 1 == 0 // evaluates to true if x is even because
110
&001
----
000
y & 1 == 0 // evaluates to false because
111
&001
----
001
The LSB of a binary number is holding the information about Parity,
any odd numbers has LBS==1 and any even has LSB==0
so when you do a bitwise and you are multiplying bit by bit
against 1, the porpouse of this is to clear all other bits but leaving the LSB just like it is (that is why multpling by 1)
A binary number can be easily identified if it's odd or even just by looking at least significant bit, wheather it is set or not(1 or 0). If least significant bit is 1 then that's an odd number else it's an even.
Just check (number % 10) if true, its odd number, else even number.

How can I invert this bit operation?

Well this is probably very easy but I'm stuck.
I'm working with a 16 bit sized long variable which holds the value of the current hour and minute.
0000 1000 0011 1111
Please note:
The first 4 bits are useless;
The last 6 bits are the hours, and the remaining represents the minutes;
There is no way to change this variable type or size;
And this is how I successfully get the hours and minutes:
hour = ((int) original_value >> 6) & 0x1F;
minute = ( (int) original_value ) & 0x3F;
How can I reverse this operation to create new original_value with different hours and minutes?
I might be missing something, but this should do the trick:
new_value = (new_hour << 6) | (new_minutes & 0x3f);
Although as others have pointed out, the way you are extracting hour is probably wrong, you should be ANDing with 0x3F, not 0x1F:
hour = ((int) original_value >> 6) & 0x3F;

Pack a date into an int variable (Java) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a problem that asks from me to pack and unpack a calendaristic date in an int variable. For example, 20th February 2007 will be represented as folows:
first 5 bits will be reserved for the day
the next 4 bits
will be reserved for the month
the last bits will be reserved for the year
Unfortunately, this is all the information I have. Any suggestions?
Assuming you are using a 32 bit signed integer and you ignore the sign bit and that by "calendaristic" you mean that it is of the type Calendar then the following method should do the trick:
public static int calToInt(Calendar cal) {
int date = cal.get(Calendar.DAY_OF_MONTH) << 26;
date |= cal.get(Calendar.MONTH) << 22;
date |= cal.get(Calendar.YEAR);
return date;
}
Note that in the implementation of Calendar, January is 0, if you want January to be represented by 1, then ensure that you add 1 to the month. Also note that based on my assumptions, your year has 22 bits to work with so will work until the year that is 2^22 i.e the year 4194304, which should be more than sufficient.
Explanation
You may not be interested in the rest but I like to explain how things work even if I only provide a rough overview:
The way this works is by taking the calendar object, getting the day and shifting it 26 bits to the left (that's what the << 26 does) which would mean that with day of month being a maximum of 5 bits, the day will actually start on the second bit of a 32bit int. This is to avoid the first bit which represents if the int is negative. If you wish to fill the full int then change 22 to 23 and 26 to 27 which will give you a bit extra for your year (double in fact). Likewise with the month of the year, it is shifted 22 bits to the left so that it comes after the day of month with a maximum consumption of 4 bits.
The |= operator is a bitwise or assignment operator. What this does is do a bitwise or of the thing on the left, with the thing on the right and assign to the thing on the left. You can do this in one line, but this is much clearer in my opinion and in terms of byte code will result in the same thing. What is meant by OR is that if either bit from either the left or right is a 1 then the output will contain a 1 in that position. This is how the individual parts are put together.
If the year did happen to be larger than the stated max, it would mess things up.
To Reverse:
In order to get this int back into a Calendar object the following method can be used:
private static Calendar intToCal(int date) {
int day = date >> 26;
int month = (date & 0b00000011110000000000000000000000) >> 22;
int year = date & 0b00000000001111111111111111111111;
return new GregorianCalendar(year, month, day);
}
This works using bitmasks and bit shifting. So the first one just shifts 26 bits along (all other bits to the right get lost and we are left with the day.
With the month and day bitmasks are used. I have written these in binary format to make it clearer exactly what it does. I am using a logical and to get only the bits from the int that I want. in the month, only the bits marked with a 1 in the bitmask will be left (this removes the day of month before we shift). I have also gotten rid of the bits on the right of the month but this is not required and will be cut off like they were in the first when the right bit shift is performed. The year just needs the mask as those last 22 bits are just simply the year in binary form. Again, I have ignored the sign bit however this is not explicit in the first and if a negative was passed it would mess this up. To fix this a mask must be applied to the day to mask the sign bit.
Change the sequence as per your requirement.
Its simple use of String#substring() and Integer#toBinaryString().
int date = 20;
int month = 2;
int year = 2007;
String d = String.format("%0$5s", Integer.toBinaryString(date));
String m = String.format("%0$4s", Integer.toBinaryString(month));
String y = String.format("%0$23s", Integer.toBinaryString(year));
String str = y + m + d;
str = str.replace(' ', '0');
System.out.println(str);
int number = 0;
for (int i = 0; i < str.length(); i++) {
number = (number << 1) | ((str.charAt(i) != '0') ? 1 : 0);
}
System.out.println(number);
System.out.println(Integer.toBinaryString(number));
get the date back from returned number
String str1=String.format("%0$32s", Integer.toBinaryString(number)).replace(' ', '0');
int originalYear= Integer.parseInt(str1.substring(0,23), 2);
int originalMonth= Integer.parseInt(str1.substring(23,27), 2);
int originalDate= Integer.parseInt(str1.substring(27,32), 2);

What is the most programatically efficient way to determine if a number is a power of 2?

Just a simple of boolean true/false that is very efficient would be nice. Should I use recursion, or is there some better way to determine it?
From here:
Determining if an integer is a power of 2
unsigned int v; // we want to see if v is a power of 2
bool f; // the result goes here
f = (v & (v - 1)) == 0;
Note that 0 is incorrectly considered a power of 2 here. To remedy
this, use:
f = v && !(v & (v - 1));
Why does this work? An integer power of two only ever has a single bit set. Subtracting 1 has the effect of changing that bit to a zero and all the bits below it to one. AND'ing that with the original number will always result in all zeros.
An Integer power of two will be a 1 followed by one or more zero's
i.e.
Value value -1 (binary)
10 2 1
100 4 11
1000 8 111
10000 16 1111
as mitch said
(value & (value-1)) == 0
when value is a power of 2 (but not for any other number apart from 1 / 0 and 1 is normally regarded as 2 raised to the power of zero).
For mitch's solution, where numbers > 0 that are not powers of 2 i.e.
value value - 1 V & (v-1)
1000001 1000000 1000000
1000010 1000001 1000000
1000100 1000011 1000000
1001000 1000111 1000000
1000011 1000010 1000010
1000101 1000100 1000100
1000111 1000110 1000110
and never zero.
Subtracting 1 from a number reverses the bits up unto and including the first 1; for power's of two's there is only one '1' so Value & (Value-1) == 0, for other numbers second and subsequent 1's are left un-affected.
Zero will need to be excluded
Another possible solution (probably slightly slower) is
A & (-A) == A
Powers of 2:
A -A
00001 & 11111 = 00001
00010 & 11110 = 00010
00100 & 11100 = 00100
Some other numbers:
A -A
00011 & 11101 = 00001
00101 & 11011 = 00001
Again you need to exclude 0 as well
To solve this problem, I did
Write the number in binary; you will see that a power of 2 has only a single one in it
Fiddle with the various operators / boolean at boolean level and see what works
doing this, I found the following also work:
A & (-A) == A
(not A) | (not A + 1) == -1 /* boolean not of a & (a-1) == 0 */
Not sure whether you mean efficient in terms of computation speed, or in terms of lines of code. But you could try value == Integer.highestOneBit(value). Don't forget to exclude zero if you need to.

check number present in a sequences

I am writing a program which I found on a coding competition website, I have sort of figured out how to solve the problem but, I am stuck on a math part of it, I am completely diluting the problem and showing what I need.
first I need to check if a number is part of a sequence, my sequence is 2*a+1 where a is the previous element in the sequence or 2^n-1 to get nth item in the sequence. so it is 1,3,7,15,31,63...
I don't really want to create the whole sequence and check if a number is present, but I am not sure what a quicker method to do this would be.
Second if I am given a number lets say 25, I want to figure out the next highest number in my sequence to this number. So for 25 it would be 31 and for 47 it would be 63, for 8 it would be 13.
How can i do these things without creating the whole sequence.
I have seen similar questions here with different sequences but I am still not sure how to solve this
Start by finding the explicit formula for any term in your sequence. I'm too lazy to write out a proof, so just add 1 to each term in your sequence:
1 + 1 = 2
3 + 1 = 4
7 + 1 = 8
15 + 1 = 16
31 + 1 = 32
63 + 1 = 64
...
You can clearly see that a_n = 2^n - 1.
To check if a particular number is in your sequence, assume that it is:
x = 2^n - 1
x + 1 = 2^n
From Wikipedia:
The binary representation of integers makes it possible to apply a
very fast test to determine whether a given positive integer x is a
power of two:
positive x is a power of two ⇔ (x & (x − 1)) equals to zero.
So to check, just do:
bool in_sequence(int n) {
return ((n + 1) & n) == 0;
}
As #Blender already pointed out your sequence is essentially 2^n - 1, you can use this trick if you use integer format to store it:
boolean inSequence(int value) {
for (int i = 0x7FFF; i != 0; i >>>= 1) {
if (value == i) {
return true;
}
}
return false;
}
Note that for every elements in your sequence, its binary representation will be lots of 0s and then lots of 1s.
For example, 7 in binary is 0000000000000000000000000000111 and 63 in binary is 0000000000000000000000000111111.
This solution starts from 01111111111111111111111111111111 and use an unsigned bitshift, then compare if it is equal to your value.
Nice and simple.
How to find the next higher number :
For example, we get 19 ( 10011 ) , should return 31 (11111)
int findNext(int n){
if(n == 0) return 1;
int ret = 2; // start from 10
while( (n>>1) > 0){ // end with 100000
ret<<1;
}
return ret-1;
}

Categories