Simplifying Conditional Operators - java

My friend wrote this code for an assignment in his programming class:
public class test {
public static void main(String args[]) {
double x = 0.9;
double y = 0.1;
boolean truth = x < 1 && x > 0 && y < 1 && y > 0;
System.out.println(truth);
}
}
I'm wondering (for myself) if there's a way to simplify the conditional operators in this line specifically:
boolean truth = x < 1 && x > 0 && y < 1 && y > 0;

Your only option for a one-liner is to use parenthesis. Personally, I prefer multiple statements to make things much clearer:
boolean isXInRange = x > 0 && x < 1;
boolean isYInRange = y > 0 && y < 1;
boolean truth = isXInRange && isYInRange;

No, but it might be made clearer (opinion):
boolean truth = (0 < x && x < 1 && 0 < y && y < 1);
The flipping of the zero check makes it easy to read as 0 < x < 1. Is that clearer? A very little bit.
The parenthesis is a style choice. Since boolean expressions are always parenthesized in if statements and while loops, I find it clearer to always parenthesize boolean operators.

My suggestion for Java:
public boolean betweenExclusive(double start, double end, double val) {
return val > start && val < end;
}
and then:
boolean truth = betweenExclusive(0, 1, x) && betweenExclusive(0, 1, y);
or a little bit fancier ;)
boolean truth = Stream.of(x, y).allMatch(x => betweenExclusive(0, 1, x));

I am simply combining two answers (#Andreas and #Justin Niessner) here, so real credit goes to them.
boolean isXInRange = 0 < x && x < 1;
boolean isYInRange = 0 < y && y < 1;
boolean truth = isXInRange && isYInRange;
Hope this helps!

Related

How does one put a ternary operator inside the parenthesis of a for loop

I've recently learnt ternary operators and was practising them by making some old code i wrote a while back nicer. When trying to do this to a for loop in many different ways I can't seem to figure out how to do it. Ive tried:
for (hotbarFirst ? (x = 0; x < mc.player.inventoryContainer.getInventory().size(); x++) :
(x = mc.player.inventoryContainer.getInventory().size(); x > 0; x--)) {
and
for (hotbarFirst ? (x = 0) : (x = mc.player.inventoryContainer.getInventory().size());
hotbarFirst ? (x < mc.player.inventoryContainer.getInventory().size()) : (x > 0);
hotbarFirst ? (x++) : (x--)){
}
The first way gives me unexpected token errors and the second one gives me not a statement errors. It seems like I should be able to do this in some way or another, so am I just approaching it wrong or is there another way to do this without making two for loops.
(ignore the functions, they're for a game I made the mod in)
(Also incase you didnt notice I'm trying to iterate over a set of numbers two either back to front or front to back depedning on whether the bool is true or false)
original code:
public static int getItem(Item itemofChoice, boolean hotbarFirst) {
if (mc.player == null) return -1;
for (int x = 0; x < mc.player.inventoryContainer.getInventory().size(); x++) {
if ((x == 0 || x == 5 || x == 6 || x == 7 || x == 8)) continue;
ItemStack s = mc.player.inventoryContainer.getInventory().get(x);
if (s.isEmpty()) continue;
if (s.getItem().equals(itemofChoice)) return x;
}
return -1;
}
Im trying to make it iterate the opposite way if the bool param is true
Here is one way to do it:
int size = mc.player.inventoryContainer.getInventory().size();
for (int x = (hotbarFirst ? 0 : size-1); (hotbarFirst ? x < size : x >= 0) ; x += (hotbarFirst ? 1 : -1)) {
...
}

Writing Java long If/Else Loops in a shorter way

Hi guys i currently have a assignment which i just finished but their is one detail i dont love about it. Is there a way to shorten if else loops
Currently i have wrote
if (x >=300) {
set y = 1;
}
else if(x >=200) {
set y = 2;
}
else if (x >=150) {
set y = 3;
}
else if (x>=100) {
set y = 4;
}
else if (x >=50) {
set y = 5;
}
else if (x >=25) {
set y = 6;
}
Probably me just being pedantic, thanks in advance
You could shorten it to
y = x>=300 ? 1 : x>=200 ? 2 : x>=150 ? 3 : x>=100 ? 4 : x>=50 ? 5 : 6;
but while that may be more compact, it is also subjectively less readable. For additional informatione, see here.
This looks like a place where you could use the switch statement. However, the switch statement is designed to handle known values rather than inequalities. If you don't like the way the chain of if-else statements looks, you could do it all in an inline expression (Ternary Operator), but that makes it hard to read.
I'd say keep the code the way it is unless there's a good reason to change it. If you're only going to have one code statement after each statement, then you can eliminate the curly braces {} to make the code look a little cleaner:
if (x >= 300) set y = 1;
else if (x >= 200) set y = 2;
else if (x >= 150) set y = 3;
else if (x >= 100) set y = 4;
else if (x >= 50) set y = 5;
else if (x >= 25) set y = 6;

Error while using Ternary operator with int and boolean

Can you please help me understand where i m doing the mistake.
I cam across this question while doing the beginner java material.
Ques: - Show how this sequence can be rewritten using the ? operator
if(x < 0) y = 10; else y = 20;
Ans: - x < 0 ? y =10 : y =20;
But when i tried performing the same i am getting an error
public class Ternary {
public static void main(String[] args) {
int result, x, y;
result = x < 0 ? y =10 : y =20;
System.out.println(result);
}
}
Error at result:- Multiple markers at this line
- Incompatible conditional operand types int and
boolean
- Syntax error on token "=", != expected
When you use a ternary operator you're assigning the left most variable to the result of the condition. In other words you only need two variables (I'll use result and x).
So the code should be:
result = x < 0 ? 10 : 20;
This will set result = 10 if x < 0 else result will be 20!
Replace the code like this. It will work.
public static void main(String[] args) {
int result, y;
int x = -1;
// Next try with int x = 1;
result = x < 0 ? (y = 10) : (y = 20);
System.out.println(result);
}

Type mismatch exception

I am developing game, Initially I was using boolean while decalring arrays, latter it revealed that instead of using boolean I should use int in order to store state of game, When I replaced boolean with int my if statement shows type mismatch exception and The operator && is undefined for the argument type(s) boolean, int. Here is my if statement code.
int [][] dots
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawPaint(pBack);
for (int y = 0; y < numRows; y++)
{
canvas.drawLine(xStep, yCoords[y], numColumns * xStep, yCoords[y], pDot);
for (int x = 0; x < numColumns; x++)
{
if (y == 0)
{
canvas.drawLine(xCoords[x], yStep, xCoords[x], numRows * yStep, pDot);
}
if (dots[x][y])
{
boolean left = x > 0 && dots[x - 1][y];
boolean up = y > 0 && dots[x][y - 1];
if (left)
{
canvas.drawLine(xCoords[x], yCoords[y], xCoords[x - 1], yCoords[y], pLine);
}
if (up)
{
canvas.drawLine(xCoords[x], yCoords[y], xCoords[x], yCoords[y - 1], pLine);
}
if (left && up && dots[x - 1][y - 1])
{
canvas.drawCircle(xCoords[x] - xStep / 2, yCoords[y] - yStep / 2, 10, pLine);
}
}
}
}
for (int y = 0; y < numRows; y++)
{
for (int x = 0; x < numColumns; x++)
{
canvas.drawCircle(xCoords[x], yCoords[y], 20, pDot);
if (dots[x][y])
{
canvas.drawCircle(xCoords[x], yCoords[y], 15, pLine);
}
}
}
if (firstDotX != -1)
{
canvas.drawCircle(xCoords[firstDotX], yCoords[firstDotY], 25, pSelect);
}
}
That is because you cannot use the AND && and OR || operators with integers, so you may want to re-define the condition:
if (left && up && dots[x - 1][y - 1])
------------------
this is an integer
I can't give you a "real " fix, because it depends on what you are trying to do. You can try this, but may not work as you expect:
if (left && up)
Yes, when left and up are used as int variable then following if condition will give type mismatch exception
if (left && up && dots[x - 1][y - 1])
As the result of left && up will be an integer and then you are performing logical AND between an int and boolean variable, so it will give type mismatch exception.
You should use it as following way -
if (((left && up).equals(intValue) && dots[x - 1][y - 1])
Where intValue is valid out value in your case and now (left && up).equals(intValue) will give a boolean value which can easily use with other boolean value dots[x - 1][y - 1]
See logical operations on int variables -
2 | 1 = 3 and 4 | 1 = 5.
You are trying to use an int type in a conditional statement that will evaluate boolean expressions, leading to a type mismatch. Unlike other languages, in Java 0 does not correspond to false too (and variables of boolean type can only be true or false, not 0 or 1). You will have to set up an expression in the statement that will give out a boolean result.
For example, you can do:
if(dots[x][y] == 0){....}
instead of:
if(dots[x][y]){....}
Now, if you are using a specific number in your dots array that is the unwanted situation to check with, you check with that number instead of 0.
The same rules occur if there are multiple expressions combined with && and/or || operators, in your conditional statements.

Complex code/algorithm optimization (e.g. simplification) quandary

How can this code be simplified?
if (x == 0) x = 1;
else if (x == 1) x = 0;
else if (x == 2) x = 3;
else if (x == 3) x = 2;
If x is always between 0 and 3 then try this:
x ^= 1;
It toggles the least significant bit.
If x can be a value other than between 0 to 3 then you can first test for that:
if (x >= 0 && x <= 3) {
x ^= 1;
}
This is the simplest form possible:
if (x == 0) x = 1;
else if (x == 1) x = 0;
else if (x == 2) x = 3;
else if (x == 3) x = 2;
wait... that's exactly your code.
cryptic one liners are NOT simple.
You could use something like this:
int mymap[4] = {1,0,3,2};
and then in your code use this:
x = mymap[x];
To use your pseudocode notation, maybe:
if (x % 2 == 0) x = x + 1
else x = x - 1
e.g you are adding one if it is an even number, subtracting otherwise? In terms of optimization though, I don't see what is particularly slow or wrong with your original code.
if(x >= 0 && x <= 3)
if((x%2) != 0) //odd
x--;
else if((x%2) == 0) //even
x++;
Not that I think this is simpler, and it doesn't limit the case to 0..3, but:
x += (x % 2 == 0) ? 1 : -1;
x ^= x & ~3 == 0 ? 1 : 0;
Unfortunately my code was so simplified it failed to make the 30-character minimum...
A common approach for handling simple data like this is to use the switch statement.
The code would be more redable with a switch statement:
switch(x) {
case 0: x=1: break;
case 1: x=0: break;
case 2: x=3: break;
case 3: x=2; break;
}
However, it's just about code readbility, not algorithmics, nor optimization.
x^=1;
unless x can be lower than 0 or higher than 3, which the problem specification doesn't state.
if( 0 <= x && x <= 3 )
x ^= 1;
if ( x >>> 2 == 0 )
{ x ^= 1;
}
one liner:
x=(x==0)?1:((x==1)?0:(x==2)?3:(x==3)?2:x);
The best way to do this...
if(x % 2 == 0){
x = +x;
}else{
x = -x;
}
Probably using switch statements

Categories