I'm changing some C code into Java, but I have come across a statement syntax that I have not seen before and I don't know what it means.
for (unsigned int i = 0; i < SIZE; i++)
{
count[2 * SIZE + 1] += grid[i][SIZE - 1 - i] != 0;
}
When adding elements of two arrays, I've never seen '!= 0' come after it. Do you know what this statement is doing? I can't find any reference to this online.
Any help is appreciated.
grid[i][SIZE - 1 - i] != 0 is a boolean expression which (by the C standard) is evaluated to 1 if the expression is true, 0 otherwise.
The same thing can be written as following:
for (unsigned int i = 0; i < SIZE; i++)
{
if ( grid[i][SIZE - 1 - i] != 0)
{
count[2 * SIZE + 1] += 1;
}
}
Unlike in C/C++, in Java, the result of this test is a boolean not an integer (0/1), and you cannot add a boolean so it counts for 0 for false or 1 for true.
I suggest a simple test which avoids to add 0 to count uselessly. So probably faster (well, constant branching could make it slower, has to be benched) & less cryptic (that's a fact), and valid in C, C++ or Java:
if (grid[i][SIZE - 1 - i] != 0)
{
count[2 * SIZE + 1]++;
}
Booleans can be implicitly converted to integers.
It is equivalent to
(grid[i][SIZE - 1 - i] != 0) ? 1 : 0
that is, add 1 if the condition is true and zero otherwise.
Related
Suppose you have an Array A = [x, y, z, ...]
And then you compute a prefix/cumulative BITWISE-OR array P = [x, x | y, x | y | z, ... ]
If I want to find the BITWISE-OR of the elements between index 1 and index 6, how can I do that using this precomputed P array? Is it possible?
I know it works in cumulative sums for getting sum in a range, but I am not sure with bit operations.
Edit: duplicates ARE allowed in A, so A = [1, 1, 2, 2, 2, 2, 3] is a possibility.
There is impossible to use prefix/cumulative BITWISE-OR array to calculate the Bitwise-or of some random range, you can try with a simple case of 2 elements and verify yourself.
However, there is different approach, which is making use of prefix sum.
Assuming that we are dealing with 32 bit integer, we know that, for the bitwise-or sum from range x to y, the ith bit of the result will be 1 if there exists a number in range (x,y) that has ith bit is 1. So by answering this query repeatedly:
Is there any number in range (x, y) that has ith bit set to 1?
We can form the answer to the question.
So how to check that in range (x, y), there is at least a number that has bit ith set? we can preprocess and populate the array pre[n][32]which contain the prefix sum of all 32 bit within the array.
for(int i = 0; i < n; i++){
for(int j = 0; j < 32; j++){
//check if bit i is set for arr[i]
if((arr[i] && (1 << j)) != 0){
pre[i][j] = 1;
}
if( i > 0) {
pre[i][j] += pre[i - 1][j];
}
}
}
And, to check if bit i is set form range (x, y) is equalled to check if:
pre[y][i] - pre[x - 1][i] > 0
Repeat this check 32 times to calculate the final result:
int result = 0;
for (int i = 0; i < 32; i++){
if((pre[y][i] - (i > 0 ? pre[x - 1][i] : 0)) > 0){
result |= (1 << i);
}
}
return result;
A plain prefix array does not work, because in order to support arbitrary range queries it requires elements to have an inverse relative to the operator, so for example for addition that inverse is negation, for XOR that inverse is the element itself, for bitwise OR there is no inverse.
A binary indexed tree also does not work, for the same reason.
But a sideways heap does work, at the cost of storing about 2*n to 4*n elements (depending on how much is added by rounding up to a power of two), a much smaller expansion than 32*n. This won't make the most exciting use of a sideways heap, but it avoids the problems of an explicitly linked tree: chunky node objects (~32 bytes per node) and pointer chasing. A regular implicit binary tree could be used, but that makes it harder to relate its indexes to indexes in the original array. A sideways heap is like a full binary tree but, notionally, with no root - effectively we do have a root here, namely the single node on the highest level that is stored. Like a regular implicit binary tree a sideways heap is implicitly linked, but the rules are different:
left(x) = x - ((x & -x) >> 1)
right(x) = x + ((x & -x) >> 1)
parent(x) = (x & (x - 1)) | ((x & -x) << 1)
Additionally we can compute some other things, such as:
leftmostLeaf(x) = x - (x & -x) + 1
rightmostLeaf(x) = x + (x & -x) - 1
The lowest common ancestor of two nodes, but the formula is a bit large.
Where x & -x can be written as Integer.lowestOneBit(x).
The arithmetic looks obscure, but the result is a structure like this, which you can step through the arithmetic to confirm (source: The Art of Computer Programming volume 4A, bitwise tricks and techniques):
Anyway we can use this structure in the following way:
store the original elements in the leaves (odd indexes)
for every even index, store the bitwise OR of its children
for a range query, compute the OR of elements that represent a range that does not go outside the queried range
For the query, first map the indexes to leaf indexes. For example 1->3 and 3->7. Then, find the lowest common ancestor of the endpoints (or just start at the highest node) and recursively define:
rangeOR(i, begin, end):
if leftmostLeaf(i) >= begin and rightmostLeaf(i) <= end
return data[i]
L = 0
R = 0
if rightmostLeaf(left(i)) >= begin
L = rangeOR(left(i), begin, end)
if leftmostLeaf(right(i)) <= end
R = rangeOR(right(i), begin, end)
return L | R
So any node that corresponds to a range that is totally covered is used as a whole. Otherwise, if the left or right children are covered at all they must be recursively queried for their contribution, if either of them is not covered then just take zero for that contribution. I am assuming, by the way, that the query is inclusive on both ends, so the range includes both begin and end.
It turns out that rightmostLeaf(left(i)) and leftmostLeaf(right(i)) can be simplified quite a lot, namely to i - (~i & 1) (alternative: (i + 1 & -2) - 1) and i | 1 respectively. This seems awfully asymmetrical though. Under the assumption that i is not a leaf (it won't be in this algorithm, since a leaf is either fully covered or not queried at all), they become i - 1 and i + 1 respectively, much better. Anyway we can use that all the left descendants of a node have a lower index than it, and all right descendants have a higher index.
Written out in Java it could be (not tested):
int[] data;
public int rangeOR(int begin, int end) {
return rangeOR(data.length >> 1, 2 * begin + 1, 2 * end + 1);
}
private int rangeOR(int i, int begin, int end) {
// if this node is fully covered by [begin .. end], return its value
int leftmostLeaf = i - (i & -i) + 1;
int rightmostLeaf = i + (i & -i) - 1;
if (leftmostLeaf >= begin && rightmostLeaf <= end)
return data[i];
int L = 0, R = 0;
// if the left subtree contains the begin, query it
if (begin < i)
L = rangeOR(i - (Integer.lowestOneBit(i) >> 1), begin, end);
// if the right subtree contains the end, query it
if (end > i)
R = rangeOR(i + (Integer.lowestOneBit(i) >> 1), begin, end);
return L | R;
}
An alternative strategy is starting from the bottom and going up until the two sides meet, while collecting data on the way up. When starting at begin and its parent is to the right of it, the right child of the parent has a higher index than begin so it is part of the queried range - unless the parent was the common ancestor of both upwards "chains". For example (not tested):
public int rangeOR(int begin, int end) {
int i = begin * 2 + 1;
int j = end * 2 + 1;
int total = data[i];
// this condition is only to handle the case that begin == end,
// otherwise the loop exit is the `break`
while (i != j) {
int x = (i & (i - 1)) | (Integer.lowestOneBit(i) << 1);
int y = (j & (j - 1)) | (Integer.lowestOneBit(j) << 1);
// found the common ancestor, so done
if (x == y) break;
// if the low chain took a right turn, the right child is part of the range
if (i < x)
total |= data[x + (Integer.lowestOneBit(x) >> 1)];
// if the high chain took a left turn, the left child is part of the range
if (j > y)
total |= data[y - (Integer.lowestOneBit(y) >> 1)];
i = x;
j = y;
}
return total;
}
Building the tree in the first place is not trivial, building it in ascending order of indexes does not work. It can be built level-by-level, starting at the bottom. Higher nodes are touched early (for example for the first layer the pattern is 2, 4, 6, while 4 is in the second layer), but they will be overwritten anyway, it's fine to temporarily leave a non-final value there.
public BitwiseORRangeTree(int[] input) {
// round length up to a power of two, then double it
int len = input.length - 1;
len |= len >> 1;
len |= len >> 2;
len |= len >> 4;
len |= len >> 8;
len |= len >> 16;
len = (len + 1) * 2;
this.data = new int[len];
// copy input data to leafs, odd indexes
for (int i = 0; i < input.length; i++)
this.data[i * 2 + 1] = input[i];
// build higher levels of the tree, level by level
for (int step = 2; step < len; step *= 2) {
for (int i = step; i < this.data.length; i += step) {
this.data[i] = this.data[i - (step >> 1)] | this.data[i + (step >> 1)];
}
}
}
I am looking at this topcoder problem here:
http://community.topcoder.com/tc?module=ProblemDetail&rd=4725&pm=2288
Under the java section there is this code :
public class KiloManX {
boolean ddd = false;
int[] s2ia(String s) {
int[] r = new int[s.length()];
for (int i = 0; i < s.length(); i++) {
r[i] = s.charAt(i) - '0' ;
}
return r;
}
public int leastShots(String[] damageChart, int[] bossHealth) {
int i, j, k;
int n = damageChart.length;
int[][] dc = new int[n][];
int[] cost = new int[1 << n];
for (i = 0; i < n; i++) {
dc[i] = s2ia(damageChart[i]) ;
}
for (i = 1; i < 1 << n; i++) {
cost[i] = 65536 * 30000;
for (j = 0; j < n; j++) {
int pre = i - (1 << j);
if ((i & (1 << j)) != 0) {
cost[i] = Math.min(cost[i], cost[pre] + bossHealth[j]) ;
for (k = 0; k < n; k++) {
if ((i & (1 << k)) != 0 && k != j && dc[k][j] > 0) {
cost[i] = Math.min(cost[i],
cost[pre] + (bossHealth[j] + dc[k][j] - 1) / dc[k][j]);
}
}
}
}
}
return cost[(1 << n) - 1] ;
}
static void pp(Object o) {
System.out.println(o);
}
}
I am trying to understand what he is been done. So what I understand is :
i - keeps track of the visited nodes somehow(this is the most baffling part of the code)
j - is the monster we want to defeat
k - is the previous monster's weapon we are using to defeat j
dc is the input array of string into a matrix
cost, keep cost at each step, some sort of dynamic programming? I don't understand how cost[1 << n] can give the result?
What I understand is they are going through all the possible sets / combinations. What I am baffled by (even after executing and starring at this for more than a week) is:
how do they keep track of all the combinations?
I understand pre - is the cost of the previous monster defeated (i.e. how much cost we incurred there), but I don't understand how you get it from just (i - 1 << j).
I have executed the program(debugger), stared at it for more than a week, and tried to decode it, but I am baffled by the bit-manipulation part of the code. Can someone please shed light on this?
cost, keep cost at each step, some sort of dynamic programming?
They are partial costs, yes, but characterizing them as per-step costs misses the most important significance of the indices into this array. More below.
I don't understand how cost[1 << n] can give the result?
That doesn't give any result by itself, of course. It just declares an array with 2n elements.
how do they keep track of all the combinations?
See below. This is closely related to why the cost array is declared the size it is.
I understand pre - is the cost of the previous monster defeated (i.e. how much cost we incurred there), but I don't understand how you get it from just (i - 1 << j).
Surely pre is not itself a cost. It is, however, used conditionally as an index into the cost array. Now consider the condition:
if ((i & (1 << j)) != 0) {
The expression i & (1 << j) tests whether bit j of the value of i is set. When it is, i - (1 << j) (i.e. pre) evaluates to the the result of turning off bit j of the value of i. That should clue you in that the indices of cost are bit masks. The size of that array (1 << n) is another clue: it is the number of distinct n-bit bitmasks.
The trick here is a relatively common one, and a good one to know. Suppose you have a set of N objects, and you want somehow to represent all of its subsets (== all the distinct combinations of its elements). Each subset is characterized by whether each of the N objects is an element or not. You can represent that as N numbers, each either 0 or 1 -- i.e. N bits. Now suppose you string those bits together into N-bit numbers. Every integer from 0 (inclusive) to 2N (exclusive) has a distinct pattern of its least-significant N bits, so each corresponds to different subset.
The code presented uses exactly this sort of correspondence to encode the different subsets of the set of bosses as different indices into the cost array -- which answers your other question of how it keeps track of combinations. Given one such index i that represents a subset containing boss j, the index i - (1 << j) represents the set obtained from it by removing boss j.
Roughly speaking, then, the program proceeds by optimizing the cost of each non-empty subset by checking all the ways to form it from a subset with one element fewer. (1 << n) - 1 is the index corresponding to the whole set, so at the end, that element of cost contains the overall optimized value.
I was attempting the powerset problem with iteration and bit shifting.
There is a particular behaviour I am unable to comprehend.
I would have expected all the 3 statement below to indicate testing if jth bit in i is set.
Why are the results different then?
private static void printSubsetInBit(Integer[] arr) {
for(int i=0;i<(1<<arr.length);i++){
List<Integer> pack=new ArrayList<Integer>();
for(int j=0;j<arr.length;j++){
//if(((i>>j)&1)==1){ -->>>> WORKS
//if((i & ( 1<<j))>0){-->>>> WORKS
if((i & ( 1<<j))==1){ -->>>> DOES NOT WORK
pack.add(arr[j]);
}
}
System.out.println(pack.toString());
}
}
If you left-shift 1 by j and then use it to mask i, you have to compare the result to the result of left-shifting 1 by j, not to 1.
In other words the condition should be
((i & (1 << j)) == (1 << j))
Or just "!= 0" would be fine.
(i & ( 1<<j))==1 is false unless j == 0, because ((1<<j) & 1 == 0) == (j != 0) (*).
This is simply not equivalent to the other expressions.
(*) Well, j % 32 == 0/j % 32 != 0; the second operand is masked.
I'm writing a simple algorithm to check the primality of an integer and I'm having a problem translating this Java code into Python:
for (int i = 3; i < Math.sqrt(n); i += 2) {
if (n % i == 0)
return false;
}
So, I've been trying to use this, but I'm obviously skipping the division by 3:
i = 3
while (i < int(math.sqrt(n))):
i += 2 # where do I put this?
if (n % i == 0):
return False
The only for-loop in Python is technically a "for-each", so you can use something like
for i in xrange(3, int(math.sqrt(n)), 2): # use 'range' in Python 3
if n % i == 0:
return False
Of course, Python can do better than that:
all(n % i for i in xrange(3, int(math.sqrt(n)), 2))
would be equivalent as well (assuming there's a return true at the end of that Java loop). Indeed, the latter would be considered the Pythonic way to approach it.
Reference:
for Statements
xrange
all
A direct translation would be:
for i in range(3, int(math.sqrt(n)), 2):
if n % i == 0:
return False
In a Java for loop, the step (the i += 2 part in your example) occurs at the end of the loop, just before it repeats. Translated to a while, your for loop would be equivalent to:
int i = 3;
while (i < Math.sqrt(n)) {
if (n % i == 0) {
return false;
}
i += 2;
}
Which in Python is similar:
i = 3
while i < math.sqrt(n):
if n % i == 0:
return False
i += 2
However, you can make this more "Pythonic" and easier to read by using Python's xrange function, which allows you to specify a step parameter:
for i in xrange(3, math.sqrt(n), 2):
if n % i == 0:
return False
Use a basic Python for i in range loop:
for i in range(3, math.round(math.sqrt(x)), 2):
if (n % i == 0):
return false
I get this answer from an automatic translation by AgileUML:
def op(self, n) :
result = False
i = 0
i = 3
while i < math.sqrt(n) :
if n % i == 0 :
return False
else :
pass
i = (i + 2)
return True
It seems to be semantically correct?
What is the most elegant way to do the next stuff:
int i = oneOrZero;
if (i == 0) {
i = 1;
} else {
i = 0;
}
You can assume that i can have only 1 or 0 value.
i ^= 1;
XOR the value with 1. This gives you both ways (in case you need to flip 0 <--> 1 either way):
0 ^ 1 = 1
1 ^ 1 = 0
subtraction?
i = 1 - i;
i = (i == 0)?1:0 is one way, though I like #Jimmy's and #Yuval's versions better.
i = ( i + 1 ) % 2, though I think we all agree the subtraction or xor method is better! (Though it has the added benefit of "flipping the switch" for more than binary.)
Use Bitwise XOR operator:
i ^= 1;
int x = 0;
x=(int)Math.cos(x);
System.out.println("X value "+x);