Java logical test questions - java

I've been solving a few problems about logic tests for AP Computer Science but I happened to get stuck on a few questions.
Here are the directions from the website: Translate each of the following English statements into logical tests that could be used in an if/else statement. Write the appropriate logical test for each statement below. Assume that three int variables, x, y, and z, have already been declared.
These are the 2 questions I have problems with:
Either x or y is even, and the other is odd.
x and z are of opposite signs.
I've been trying to find these answers out for a couple of hours and I still have no clue. I would appreciate it if someone could guide me in the right direction. I understand this is "homework" but some definitive help would be very helpful.

For the first question: x % 2 != y % 2
Second question: x * z < 0

You'll need to use and (&&) and or (||) to make a logic formula. I'm not going to do yours, but here's another one:
x is bigger than both y and z or x is less than both y and z.
Translates to:
((x > y) && (x > z)) || ((x < y) && (x < z))
You just need to figure out a formula for odd/even (hint - the low order bit) and for positive/negative (hint - compare with 0), and combine those with and/or.

For the first question, if x (or y)* is odd, y (or x) must be even, and vice versa. Checking for odd values implies that the modulo of x and 2 is 1 - from there, you would have to assert if y (or x) modulo 2 is 0 (to check for evenness).
For the second question, you would need to follow a chain of logic as such:
X is positive (or greater than 0), which implies Z must be negative (or less than 0).
Z is positive, which implies that X must be negative.
*: This is an exclusive or - I mean that you're either checking x or y, but not both at the same time.

First you have to fully understand the statement in order to put it into the language of a computer. For example,
x and y have the same sign
What this really means is:
( x is greater than or equal to 0 and y is greater than or equal to 0 ) or ( x is less than 0 and y is less than 0 )
Now it is easy to put this into Java:
(x >= 0 && y >= 0) || (x < 0 && y < 0)
Of course, your questions can be solved via a similar method.

Either x or y is even, and the other is odd.
The sum of an odd and even number is odd. The sum of two odd numbers is even and the sum of two even numbers are even.
So (x+y)%2!=0.
x and z are of opposite signs
This one is similar, you can do:
x*z<0
Since 0 is neither negative or positive and
neg * pos = neg
neg * neg = pos
pos * pos = pos
If you want to consider 0 and a negative number of opposite signs you can use (x >= 0) == (z < 0)

Putting it in plain english, for me anyhow.
If ((x is even AND y is odd) OR (x is odd AND y is even))
For the other
If ((x gt or eq 0 AND y lt 0) OR (y gt or eq 0 AND x lt 0))
Assuming 0 is positive.

Related

More efficient way to check if a value is included in an array?

Writing a game that does lots of comparisons, and it's lagging. I'm trying to speed it up, and this particular chunk of code is run thousands of times every frame, for different values of x y and z. Is there a better way to check if the values of x y and z are valid in the array? (java)
if (x >= 0 && x < blocksArr.length && y >= 0 && y < blocksArr[x].length && z >= 0 && z < blocksArr[x][y].length && blocksArr[x][y][z])
I've tried checking if blocksArr[x][y][z] != null and checking if blocksArr[x][y][z] != undefined but neither give results.
In general, the most efficient way of doing t >= 0 && t < u with u known to be positive is to compare the unsigned value of t and u using Integer.compareUnsigned(t, u) < 0. As a result, your if can be more efficiently expressed as
if (Integer.compareUnsigned(x, blocksArr.length) < 0 &&
Integer.compareUnsigned(y, blocksArr[x].length) < 0 &&
Integer.compareUnsigned(z, blocksArr[x][y].length) < 0 &&
blocksArr[x][y][z])
However, I think your representation of blocksArr as a 3-dimensional array is really inefficient and results in a lot of indirections, which greatly hinders the potential performance. A more logical approach is to represent it as a single array and have length, width, height being stored separately. This would result in your code looks something like this:
if (Integer.compareUnsigned(x, length) < 0 &&
Integer.compareUnsigned(y, width) < 0 &&
Integer.compareUnsigned(z, height) < 0 &&
blocksArr[x * (width * height) + y * height + z])
This however limits your block to around 2 billion elements, to overcome this limitation, you need to resort to the Memory Access API, which is currently in preview. It has an important advantage that it allows the allocation and deallocation of memory blocks to be deterministic, which is much more desirable for too large memory pieces. Using a memory segment to represent the blocksArr, your code would become:
if (Long.compareUnsigned(x, length) < 0 &&
Long.compareUnsigned(y, width) < 0 &&
Long.compareUnsigned(z, height) < 0 &&
blocksArr.get(ValueLayout.JAVA_BOOLEAN, x * (width * height) + y * height + z))
Moreover, since blocksArr is a block of boolean values, packing them so that each element occupies only 1 bit will improve the memory consumption and cache pressure greatly. The check now can be expressed as:
long index = x * (width * height) + y * height + z;
long byteIndex = index >>> 3;
int shift = (int)(index & 7);
if (Long.compareUnsigned(x, length) < 0 &&
Long.compareUnsigned(y, width) < 0 &&
Long.compareUnsigned(z, height) < 0 &&
blocksArr.get(ValueLayout.JAVA_BYTE, byteIndex) & (1 << shift) != 0)
I don't know java but in general, I would expect the following to be at least as fast, possibly faster.
Your compiler may do something like this anyway so it might not be faster. You can split the 'If' statement up so that it will do fewer lookups. Sorry, but I'll have to write it as c code. You can get the idea and translate to java.
if (x >= 0 && y >= 0 && z >= 0 && x < blocksArr.length) {
if (y < blocksArr[x].length && z < blocksArr[x][y].length && blocksArr[x][y][z]) {
.....
}
}
Assuming user16320675 is correct about the evaluation order, you could use one 'if' statement. I don't know how the java compiler works.
if (x >= 0 && y >= 0 && z >= 0 && x < blocksArr.length && y < blocksArr[x].length && z < blocksArr[x][y].length && blocksArr[x][y][z]) .....
What you are doing is a bounds check, to make sure that the indexes x, y, and z are valid indices in the blocksArr[][][] array. In C, this is necessary as C allows you to go outside the array.
Java, however, does a bounds check every time you access the array. So you are doing a manual bounds check, then another check, plus Java is doing a check on two dimensions, and finally Java does another check on three dimensions.
All you really need to do is access the array, let Java do the bounds check, and catch an exception if any of the indices are out of bounds.
boolean value;
try
{
value = blocksArr[x][y][z];
}
catch (ArrayIndexOutOfBoundsException e )
{
value = false;
}
There is some overhead in setting up a try/catch block, but overall it should be faster.
You have a box determined by three dimensions, x, y, and z.
If any of those indices are outside the boundaries of the box, then the entire if() statement is false. So there is no need to walk through things like blocksArr[x].length
Also, think about what is actually going on under the hood. The variable x is in fact a pointer to a location in memory which holds the value. To process a statement like x >= 0, the computer must locate the memory location for x, fetch that value and put it into one of its internal registers, say register A. It then takes that value 0 and puts it into register B. It compares Register A to register B. if A > B, then it goes on to the next operation, otherwise it compares A to B again. If the comparison is zero, then it goes to the next operation, otherwise it move the operation pointer past the if() statement.
For comparing x < blocksArr.length, it again fetches x, then fetches blocksArr calculates the offset to the length value, then fetches that into the register, where it does the comparison.
You can shorten all of this by using some static constants.
Consider that x >= 0 can be re-written as x > -1. This can potentially reduce 2 comparisons to 1, so a few CPU cycles saved.
An array construct is an immutable object, that is it cannot be changed after being created. So an array's length will never be different. So if you created an array with size 5, blocksArr.length will always return 5. in the comparison x < blocksArr.length you could substitute x < 5, which means the CPU does not need to fetch blocksArr.length, which saves CPU cycles.
So you could re-write the array creation, and your if statement to:
public static final int MAX_X = 10;
public static final int MAX_Y = 15;
public static final int MAX_Z = 20;
public boolean blocksArr[][][] = new boolean[MAX_X][MAX_Y][MAX_Z];
.
.
.
if ( ( x > -1 && x < MAX_X ) && // validate for X dimension
( y > -1 && y < MAX_Y ) && // validate for Y dimension
( z > -1 && z < MAX_Z ) && // validate for Z dimension
blocksArr[x][y][z] ) // check value
I think this is the least CPU intensive way of doing this.

Algorithm to find the maximum acceptable values of the variables

I need an algorithm that gives me the maximum acceptable values of the variables under the equation system in Java. I could use Cramer's Algorithm but I thinks there are faster algorithms to solve this.
Edit:
It is not about maximizing a target function but simply looking under these restrictions what maximum value can any variable take.
Example:
x1 <= 4
x2 <= 4
x1 + x2 <= 6
-x1 + 2x3 <= 4
x1 >= 0
x2 >= 0
x3 >= 0
Solution:
x1 <= 4
x2 <= 4
x3 <= 4
Read through the input with any kind of Scanner or InputStreamReader class.
Using StringTokenizer, take the first variable name. Get the next token, the operator.
Using the number on the right (assuming the operator is < or <=) repeatedly find the max value of the given number.
If you have >= or > operators, you can also get a min value of the given number.

Can someone explain to me this code of multiplying two variables using shifts? [duplicate]

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

Java- for loop using << operator

I'm stuying this code and I don't understand what this line does: [(y << 3) + x]
for (int y = 0; y <= 7; ++y) {
for (int x = 0; x <= 7; ++x) {
final String pieceCode = pieceCodes[(y << 3) + x];
if (pieceCode.length() != 2) throw new IllegalArgumentException();
if (!pieceCode.equals("--")) {
pieces[((7 - y) << 3) + x] = CheckersPiece.valueOf(pieceCode.charAt(0), pieceCode.charAt(1));
}
}
}
It's an obfuscated way of multiplying by 8. Thus, (y << 3) + x is equal to 8 * y + x.
The reason that y << 3 is equivalent to multiplying by 8 is because << is the left-shift operator: it shifts all the bits of y left by one position. In the same way that if you take a base-10 number and shift left by one position you have multiplication by 10, shifting left in base-2 is equivalent to multiplying by 2. Therefore, shifting left by three positions is equivalent to multiplying by 2 * 2 * 2 = 8. In general, shifting left by n positions is equivalent to multiplying by 2^n (as long as you don't have bits falling off of the left end).
In the olden days, programmers wrote code like this because left shifts are super duper fast, faster than multiplication and so 8 * y was less optimal than y << 3. But these days, compilers are pretty good at figuring out when to replace something like 8 * y with y << 3.
Therefore, I say it's obfuscated because 8 * y more clearly expresses the intent: the intent of (y << 3) + x is to skip by y blocks of 8, and take the xth position in that block. And this is much more clearly expressed by saying 8 * y + x. Remember, we code in high-level languages for humans to read and understand the code. Our code should be written for the humans. The compiler can do its job of making good machine instructions for the machine to understand.
It's done this way because it's trying to pretend that pieceCodes is a 2D array, just mapped into a 1D array.
That is, piecesCode looks like this
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
but we can pretend it looks like this
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
See, given (x, y) -> 8y + x we accessing the xth column, yth row of piecesCode. That is, y tells us how many blocks of 8 to skip, and x tells us where to go within that block.
(y << 3) means bit shifting 3 times to the left. It's the same as multiplying by 2^3 = 8. So, whole expression (y << 3) + x becomes y * 8 + x.
It should be written in the form y * 8 + x, because it's more readable and very probably there is no performance gain. Premature optimization is the root of all evil. It's better to left such micro optimizations to the compiler (or JVM).
Moreover, board size could be stored in a constant, to have it only in one place:
final int SIZE = 8;
// ...
for (int y = 0; y < SIZE; y++) {
for (int x = 0; x < SIZE; x++) {
final String pieceCode = pieceCodes[y * SIZE + x];
y * 8 + x is just iterating over a (logically) 2D table with 8 rows and columns, stored as 1D, with 64 cells.
As a final remark, I would like to point out, that in the given code pieceCodes is an array of Strings...
But in fact, it's an array of piece codes. Not just some Strings. Now, "--" works as some magic state and nobody except the programmer knows, what it means. if (pieceCode.length() != 2) also looks bad. So, there should be an object PieceCode and array will be declared as PieceCode[] pieceCodes. In PieceCode we can implement proper equals() method. If PieceCode is only a state, it can be an Enum. For example EMPTY, WHITE_PAWN, WHITE_QUEEN, BLACK_PAWN, BLACK_QUEEN. Comparing Strings is not as fast as comparing Enums. We also have to watch out to write equals(), instead of ==.
From the spec:
The value of n << s is n left-shifted s bit positions; this is equivalent (even if overflow occurs) to multiplication by two to the power s.
<< and >> are bit shift operators. In this case, it converts y to binary and "shifts" over 3 places, adding new bits to the end as required
For example, if y was 8, it would have the value of 1000
y<<3 would shift to the left 3 bits, resulting in 1000000, or 64
That is called a bitwise and bit shift operator. Also, check out the wiki.
Summary of the documentation
The Java programming language also provides operators that perform bitwise and bit shift operations on integral types. The operators discussed in this section are less commonly used.
The unary bitwise complement operator "~" inverts a bit pattern. The signed left shift operator "<<" shifts a bit pattern to the left, and the signed right shift operator ">>" shifts a bit pattern to the right.
The bitwise & operator performs a bitwise AND operation.
The bitwise ^ operator performs a bitwise exclusive OR operation.
The bitwise | operator performs a bitwise inclusive OR operation.
Example code:
class BitDemo {
public static void main(String[] args) {
int bitmask = 0x000F;
int val = 0x2222;
// prints "2"
System.out.println(val & bitmask);
}
}
So... What is a bitwise and bit shift operator?
In order to save time and space, I'll simply include this article explaining all operators in depth!
The code uses an optimization technique that represents a two dimensional array[m][n] as a one dimensional array[m*n]. Both m and n appear to be 8 here (8-queens, chess, maybe?).
The trick is to transpose index tuples (i,j) to indexes for the one dimensional array.
Most of the time, you do this by multiplying i with n and add j.
Since n=8, multiplication can be expressed in this case by shifting 3 bits left. This conveys the message "We are doing adress arithmetic here on some nicely sized (i.e. in terms of power of 2) arrays.", at least to the non-novices.
Quick answer, it's an efficient way of multiplying a number by 8 (2^3=8)
y << 3 means "shifted 3 bits left" ... which is, essentially, another way to do "* 8"
If you do a right-shift (y >> 3), that would be integer divide by eight, but is also useful because the bits fall off the end, and you sort of "drain" the bits if you loop.
It used to be (way way back when) that CPU shift was faster than multiplication, so using "x << 1" was faster than "x * 2". However, that's not true anymore.
I used to see expressions in code like "x << 4 + x << 2 + x << 1" ... which is really "x * 16 + x * 4 + x * 2" or "x * 22".
http://en.wikipedia.org/wiki/Bitwise_operation ... In Java, all integer types are signed, and the "<<" and ">>" operators perform arithmetic shifts. Java adds the operator ">>>" to perform logical right shifts, but because the logical and arithmetic left-shift operations are identical, there is no "<<<" operator in Java.

Why do I get -1 from this statement?

if(heading == 2){
nextY = (y-1) % 20;
nextX = x;
}
When debugging this program, my heading is 2 and y = 0, however, when I come to this if statement, nextY becomes -1. Why is it not cycling properly? (0-19)?
That's how mod operation generally works for negative numbers in programming (in all languages I tried it in).
But you can easily make number positive before doing mod
nextY = (y + 20 - 1) % 20;
Modulo operators often return negative numbers for negative inputs. For example, C# will give you a number from -356..359 for the expression x % 360.
Instead of subtracting 1 then taking modulo 20, you can add 19, which is the same thing but keeps the number positive, or you can use the ternary operator:
nextY = (y+19) % 20; // or
nextY = (nextY == 0) ? 19 : nextY - 1;

Categories