See the edit history of "Making a basic algorithm". There was a palpable sense of disappointment amongst the respondents when OP changed the question, invalidating some interesting answers. So, I figure, why not ask the original question again, to allow those answers to stand.
So basically I want to find a easier way to do this:
if(size == 2) unit /= 2;
if(size == 2 || size == 6) unit /= 2;
if(size == 2 || size == 6 || size == 10) unit /= 2;
So basically it checking if size is equal to 2 and then every new line it add 4 to the last size check.
I need to go up to 256.
I want to know if there a easy way of doing this.
The fundamental criterion on the numbers checked for equality here is that the remained of size / 4 is 2. This can be detected using the modulo operator, %:
size % 4 == 2
Then there is the question of how many times to divide unit by 2. For the examples above:
For size == 2, unit /= 8 (matches all 3 conditions);
For size == 6, unit /= 4 (matches second 2 conditions);
For size == 10, unit /= 2 (matches last condition).
So the smaller the number, the more times it is divided by 8. If the maximum size checked is 10, unit is divided by 2 ^ (1 + (10 - size) / 4). This can be expressed concisely using the right-shift operator:
unit >>= 1 + (10 - size) / 4
or, more generally:
unit >>= 1 + (max_number - size) / 4
where max_number % 4 == 2.
Setting max_number = 254 (256 is specified in the question, but wouldn't feature in the expression; the last number checked would be 254), and noting that we only apply this if 2 <= size <= 254, we can express the final answer as:
if (size % 4 == 2 && size >= 2 && size <= 254) {
unit >>= 1 + (254 - size) / 4;
}
Actually, the condition can be expressed more concisely (but undoubtedly less readably) as:
if ((size & 0xffffff03) == 2)
As noted by #PaulBoddington, care needs to be taken with the size of the right shift: if unit is an int and the number of bits shifted is greater than 31, then unit should simply be set to zero.
Related
This is one of the questions that I faced in competitive programming.
Ques) You have an input String which is in binary format 11100 and you need to count number of steps in which number will be zero. If number is odd -> subtract it by 1, if even -> divide it by 2.
For example
28 -> 28/2
14 -> 14/2
7 -> 7-1
6 -> 6/2
3 -> 3-1
2 -> 2/2
1-> 1-1
0 -> STOP
Number of steps =7
I came up with the following solutions
public int solution(String S) {
// write your code in Java SE 8
String parsableString = cleanString(S);
int integer = Integer.parseInt(S, 2);
return stepCounter(integer);
}
private static String cleanString(String S){
int i = 0;
while (i < S.length() && S.charAt(i) == '0')
i++;
StringBuffer sb = new StringBuffer(S);
sb.replace(0,i,"");
return sb.toString();
}
private static int stepCounter(int integer) {
int counter = 0;
while (integer > 0) {
if (integer == 0)
break;
else {
counter++;
if (integer % 2 == 0)
integer = integer / 2;
else
integer--;
}
}
return counter;
}
The solution to this question looks quite simple and straightforward, however the performance evaluation of this code got me a big ZERO. My initial impressions were that converting the string to int was a bottleneck but failed to find a better solution for this. Can anybody please point out to me the bottlenecks of this code and where it can be significantly improved ?
If a binary number is odd, the last (least significant) digit must be 1, so subtracting 1 is just changing the last digit from 1 to 0 (which, importantly, makes the number even).
If a binary number is even, the last digit must be 0, and dividing by zero can be accomplished by simply removing that last 0 entirely. (Just like in base ten, the number 10 can be divided by ten by taking away the last 0, leaving 1.)
So the number of steps is two steps for every 1 digit, and one step for every 0 digit -- minus 1, because when you get to the last 0, you don't divide by 2 any more, you just stop.
Here's a simple JavaScript (instead of Java) solution:
let n = '11100';
n.length + n.replace(/0/g, '').length - 1;
With just a little more work, this can deal with leading zeros '0011100' properly too, if that were needed.
Number of times you need to subtract is the number of one bits which is Integer.bitCount(). Number of times you need to divide is the position of most-significant bit which is Integer.SIZE (32, total number of bits in integer) minus Integer.numberOfLeadingZeros() minus one (you don't need to divide 1). For zero input I assume, the result should be zero. So we have
int numberOfOperations = integer == 0 ? 0 : Integer.bitCount(integer) +
Integer.SIZE - Integer.numberOfLeadingZeros(integer) - 1;
As per the given condition, we are dividing the number by 2 if it is even which is equivalent to remove the LSB, again if number is odd we are subtracting 1 and making it an even which is equivalent to unset the set bit (changing 1 to 0). Analyzing the above process we can say that the total number of steps required will be the sum of (number of bits i.e. (log2(n) +1)) and number of set bits - 1(last 0 need not to be removed).
C++ code:
result = __builtin_popcount(n) + log2(n) + 1 - 1;
result = __builtin_popcount(n) + log2(n);
I have been studying Java HashMap source code, the part of it which decides in what bucket to put an object and saw this change in Java 7 (8) as compared to Java 6.
Additionally I conducted numerous experiments and both expressions yeild the same result:
hash % n
and
hash & (n - 1)
where n - the array length that must be power of 2.
I just cannot figure out why is it true? Is there any theorem or some math laws that prove these statement are equal? Basically I want to understand the inference and prove the equivalence of those two statements.
PS. If n is not a power of 2 number, the equivalence breaks immedeately.
If n is a power of two that mean its binary representation is 10000....,
n-1 for that matter is 1111111... with one less digit.
That means that binary &-ing with (n-1) preserves just exactly the number of bits in k that n-1 has set.
Example n = 8: 1000, n-1 = 7: 111
&-ing for example k = 201: 11001001
k % n = k & (n-1) = 11001001 & 111 = 001 = 1.
%-ing with a power of 2 means that in binary you just strip everything away that is above (including) the only set bit: for n = 8 that means stripping everything over (including) the 4th bit. And that is exactly what the &-ing does at well.
A side effect is that using & is commutative: hash & (n - 1) is equivalent to (n - 1) & hash which is not true for %, the jdk source code in many places uses the later, e.g. in getNode
Think about the bits in (n - 1) if n is a power of 2 (or ((1 << i) - 1), if you want to simplify the constraint on n):
If n is, say, 16 (= 1 << 4), then n - 1 is 15, and the bit representation of 15 and 16 (as 32-bit ints) are:
1 = 00000000000000000000000000000001 // Shift by 4 to get...
16 = 00000000000000000000000000010000 // Subtract 1 to get...
15 = 00000000000000000000000000001111
So just the lowest 4 bits are set in 15. If you & this with another int, it will only allow bits in the last 4 bits of that number to be set in the result, so the value will only be in the range 0-15, so it's like doing % 16.
However, note that this equivalence doesn't hold for a negative first operand:
System.out.println(-1 % 2); // -1
System.out.println(-1 & (2-1)); // 1
Ideone demo
The arithmetic rule for integer / and % is:
x*(y/x) + (y%x) = y
What about a negative hash -4 and a positive n 8?
8*0 + (-4%8) = -4
Hence modulo maintains the sign.
-4 % 8 = -4
-4 & 7 = 4
Or:
int t = hash%n;
if (t < 0) {
t += n;
}
assert t == (hash & (n-1));
So in the earlier java with %n hash had to be positive to begin with.
Now hash may be negative, more solid and better hashing.
So that was a sound reason for this subtle change in java source code.
Background:
2n is a 1 followed by n-1 0s (in binary).
2n - 1 is n-1 1s.
Hence for n being a positive power of 2, and some positive number h:
h % n == h & (n-1)
Another usage is to count bits in an int. The class Integer has just such a function.
int bits = 0;
while (x != 0) {
x &= x - 1;
++bits;
}
Here are my instructions:
Write a program that uses one loop to process the integers from 300 down to 200, inclusive. The program should detect multiples of 11 or 13, but not both. The multiples should be printed left-aligned in columns 8 characters wide, 5 multiples per line. When all multiples have been displayed, the program should display the number of multiples found and their sum.
int sum = 300;
while (sum >= 200 && sum <= 300 ) {
sum = sum - 1;
System.out.println( sum % 11 == 0 || sum % 13 == 0 );
}
As you may know, I am getting true and false responses rather than the numbers. I am very much stuck and would like any help or advice I can get! Thank you.
The problem is that the == operator is an equality operator that returns a condition (either true or false). That's why you're printing true and false. If you want to print the actual multiples, first check if they are either a multiple of 11 or a multiple of 13 (but not both), and then print the number, sum.
int sum = 300;
while (sum >= 200 && sum <= 300 ) {
if((sum % 11 == 0) != (sum % 13 == 0)) { //checks if sum is a multiple of 11 or 13 but not both
System.out.println(sum);
}
sum = sum - 1;
}
What (sum % 11 == 0) != (sum % 13 == 0) means is that if sum is a multiple of both 11 and 13, then the expression will equate to false because the results of (sum % 11 == 0) and (sum % 13 == 0) are both true. Similar reasoning will let you see that if sum is only a multiple of one of 11 or 13, then the expression will result in true since one side of the expression will result in true while the other side will result in false.
Since this looks like homework, I don't want to just give the answer away, but I'd like to help, so I'll give you a couple of hints:
1) "if" statements are where you'd want to use comparisons to decide what to do, e.g.
if (blah == more_blah)
2) Since your numbers are all guaranteed to be 3 characters, there is a simple and easy way to get the exact spacing of 8 characters per column. (Hint: print() and println() are both things)
3) Since you want multiple columns, you might want some way to check how many columns you have already and then decide whether you want println or print. (bonus hint: using System.out.println("") could make your code simpler.)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
So basically I want to find a easier way to do this:
if(size == 2 || size == 6 || size == 10 || size == 14 || ...) unit /= 2;
So basically it start at 2 and then it check if equals to previous size + 4.
I need to go up to 256.
I want to know if there a easy way of doing this.
EDIT: Sorry I meant to do it all in one line, not multiple lines.
You may do this:
if ( size >= 2 && size <= 256 && size % 4 == 2 )
unit /= 2;
If it keeps getting raised by 4, you could try using module-4:
if ((size - 2) % 4 == 0 && size <= 256){
unit /= 2;
}
Or, if size can be negative but should be positive:
if ((size - 2) % 4 == 0 && size >= 0 && size <= 256){
unit /= 2;
}
You could possibly do it with a switch statement as follows:
switch(size) {
case 2:
unit /=2;
case 4:
unit /= 2;
....
}
but this is still cumbersome. Another alternative could be:
for(int i=2; i < 256; i+=4) {
if (size == i) {
unit /= 4;
}
}
I'd just use an array of possible divisors.
Extend this into a class if the number to be divided by changes.
Derive the divisor on the fly if there is a mathematical progression of some kind (such as d[n+1] = d[n] + 4).
int[] divisors = {2, 6, 10};
int doIt(int n, int unit) {
for (int i : divisors) {
if (n == i) {
unit /= 2;
}
}
return unit;
}
You can ace this in O(1) with
if ((size - 2) % 4 == 0){
/*2, 6, 10 etc*/
unit >>= (Math.min(size, 256) + 2) / 4;
}
where the bitwise shift generates the appropriate multiplication of a power of two: a touchstone for your knowledge of operator precedences.
Now the question has been updated, the operation on unit is the considerably duller unit /= 2, and you'll have to add in the newly-introduced upper-bound on size of 256.
A cryptic way of doing it:
unit >>= ((size & -253) == 2) ? 1 : 0;
Explanation:
A number in the range 2-254 is also in the range 0-255. You can do a bitwise AND with ~255 = 0xffffff00; if the value is non-zero, it is outside that range;
To check calculate number % 4, do a bitwise AND with 3; compare this to 2 to see if number % 4 == 2.
So, to check if a number meets both of these criteria, we can calculate the bitwise AND of size with the bitwise AND of the two bit masks above: if both conditions are met, the result is 2.
Hence:
(size & (~255 | 3)) == 2 (simplifies to) (size & -253) == 2.
I have a problem to understand how recursion parameter calculated, which explained in this question Java recursion and integer double digit. The implemented code looks like this:
public static int doubleDigits(int i){
if (i == 0){
return 0;
}else{
return doubleDigits(i / 10) * 100 + (i % 10) * 10 + i % 10;
}
}
With the result if int i = 1234:
11223344
I tried to debug the code, but having difficulties to understand, what goes on.
I have checked many examples and, I can understand most of the cases how recursion works but not in this case.
I would like to get a easy-understandable explanation how recursion works in this case.
Recursion always works by solving a smaller problem and then adding to that solution (or combining smaller solutions).
doubleDigits(i / 10)
doubles the digits of the number having all the digits of the original number except the last one.
Then it is multiplied by 100 to make room for the remaining two digits, which are added with (i % 10) * 10 + i % 10. i % 10 is the last digit of the input number, and it is added twice to the output number.
doubleDigits(1234 / 10) * 100 + (i % 10) * 10 + i % 10
112233 * 100 + 4 * 10 + 4 = 11223344