Writing a conditional statement - java

I am a student learning Java and am stuck on the last part of a homework problem. I need to write a conditional statement that prints whether the roll of the dice was a Yahtzee or not (all five dice are equal to one another). I cannot figure out how to do this since I used ints and not boolean. I know I cannot cast an int into boolean and up to this point this casting is the only way I know how to change variables. Any help would be appreciated since the ways to achieve what I am looking for have been more than I can understand at this point.
This is what I have and the issue is in the second to last line.
import java.util.Random;
public class FiveDice_JLR
{
//-----------------------------------------------------------------
// Generates random numbers in various ranges.
//-----------------------------------------------------------------
public static void main(String[] args)
{
Random generator = new Random();
int die1, die2, die3, die4, die5;
die1 = generator.nextInt(6)+1;
System.out.println("Die 1: " + die1);
die2 = generator.nextInt(6)+1;
System.out.println("Die 2: " + die2);
die3 = generator.nextInt(6)+1;
System.out.println("Die 3: " + die3);
die4 = generator.nextInt(6)+1;
System.out.println("Die 4: " + die4);
die5 = generator.nextInt(6)+1;
System.out.println("Die 5: " + die5);
**if(die1==die2&==die3==die4&==die5&&);**
{
System.out.println("Yahtzee!!!!");
}
}

If you use just &, that is the bitwise AND, therefore it compares the bits of all the numbers. What you want is &&, which is logical AND:
if(die1 == die2 && die2 == die3 && die3 == die4 && die4 == die5) {
// Something here...
}
Also note that each && operator just like the == operator, requires 2 operands to properly compare
Assuming all your values are positive, another method to check if all numbers are equal to each other is to add them all up and check if the sum is equal to 5 times one of the values.
if((die1 + die2 + die3 + die4 + die5) == die1 * 5) {
// Something here...
}
This is doing the same thing and is shorter, but is prone to error because you may in the future decide to generate negative numbers (for some reason), or decide to use more dice and forget to change 5 to the appropriate number, etc. In general, just stick to the first one

There are two operators that will be important for checking that the values of all your dice are the same: the conditional AND operator (&&) and the equality operator (==). The Java documentation includes some good details of what these are, and how to use them.
There are a couple of things to keep in mind with these. Both of these operators are binary operators. They operate on two operands. e.g. a == b compares the value of a to b. Similarly, a && b evaluates to true if both a and b are true.
Of course, this presents a challenge when we want to compare the values of more than two operands. Say we have three variables, a, b, and c. How would we check that they all have the same value? (For simplicity, we'll assume they're all primitive types).
We know how to check that a and b are the same: a == b.
We also know how to check that b and c are the same: b == c.
If both of these are true then, by the transitive property of equality, we know that a must also be equal to c. How do we check two conditions within a single statement? Using the conditional AND operator, of course:
a == b && b == c
This was a simple example with just three variables, but this can be extended to any number of variables (say, to the values of 5 dice). Give it a try, and see if you can get it working using these two operators.

The statement you are looking for is
if(die1==die2 && die2==die3 && die3==die4 && die4==die5)
Or, for #smac89's and &duffymo's benefit, a version with &:
if(die1==die2 & die2==die3 & die3==die4 & die4==die5)
which will run slower because of fully evaluating everything, but is otherwise semantically identical.

Related

For what value of i does while (i == i + 1) {} loop forever?

I ran cross this puzzler from an advanced programming course at a UK university exam.
Consider the following loop, in which i is, so far, undeclared:
while (i == i + 1) {}
Find the definition of i, that precedes this loop, such that the while loop
continues for ever.
The next question, which asked the same question for this code snippet:
while (i != i) {}
was obvious to me. Of course in this other situation it is NaN but I am really stuck on the prior one. Does this have to do with overflow? What would cause such a loop to loop for ever in Java?
First of all, since the while (i == i + 1) {} loop doesn't change the value of i, making this loop infinite is equivalent to choosing a value of i that satisfies i == i + 1.
There are many such values:
Let's start with the "exotic" ones:
double i = Double.POSITIVE_INFINITY;
or
double i = Double.NEGATIVE_INFINITY;
The reason for these values satisfying i == i + 1 is stated in JLS 15.18.2. Additive Operators (+ and -) for Numeric Types:
The sum of an infinity and a finite value is equal to the infinite operand.
This is not surprising, since adding a finite value to an infinite value should result in an infinite value.
That said, most of the values of i that satisfy i == i + 1 are simply large double (or float) values:
For example:
double i = Double.MAX_VALUE;
or
double i = 1000000000000000000.0;
or
float i = 1000000000000000000.0f;
The double and float types have limited precision, so if you take a large enough double or float value, adding 1 to it will result in the same value.
These puzzles are described in detail in the "Java Puzzlers: Traps, Pitfalls, and Corner Cases" book by Joshua Bloch and Neal Gafter.
double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}
or:
double i = 1.0e40;
while (i == i + 1) {}
both will result in an infinite loop, because adding 1 to a floating-point value that is sufficiently large will not change the value, because it doesn't "bridge the gap" to its successor1.
A note about the second puzzle (for future readers):
double i = Double.NaN;
while (i != i) {}
also results in an infinite loop, because NaN is not equal to any floating-point value, including itself 2.
1 - Java Puzzlers: Traps, Pitfalls, and Corner Cases (chapter 4 - Loopy Puzzlers).
2 - JLS §15.21.1
double i = Double.POSITIVE_INFINITY;
Just an idea: what about booleans?
bool i = TRUE;
Isn't this a case where i + 1 == i?

Computing Pi in Java

This weeks assignment in programming is to compute Pi in java using this as the basis for the assignment:
(for 80% of the marks):
USING A WHILE OR A DO-WHILE LOOP write a program to compute PI using the following equation:
PI = 3 + 4/(2*3*4) - 4/(4*5*6) + 4/(6*7*8) - 4/(8*9*10) + ...
Allow the user to specify the number of terms (5 terms are shown) to use in the computation.
Each time around the loop only one extra term should be added to the estimate for PI.
(for 20% of the marks):
Alter your solution from part one so that the user is
allowed to specify the precision required between 1 and 8 digits
(i.e. the number of digits which are correct; e.g. to 5 digits PI is 3.14159),
rather than the number of terms. The condition on the loop should be altered so that it
continues until the required precision is obtained. Note that you need only submit this
second version of the program (assuming you have it working).
I'm only able to use the above method to compute Pi, as thats what the lecturer wants. Ive got this so far, although the code keeps giving me the same wrong answer for every even number and a different wrong answer for each odd number. Im still on part one as i havent got the right answer yet to be able to progress onto part 2.
All help would be great, as the program needs to be submitted by tueday.
Thanks in advance!
import java.util.Scanner;
public class ComputePI {
public static void main(String[] args) {
System.out.print( "Please enter the amount of decimal "
+ "digits of PI, you would like to set it too");
Scanner termScan = new Scanner( System.in );
int term = termScan.nextInt();
termScan.close();
double pi = 3.0;
int loopCount = 2;
int number = 2;
while ( loopCount <= term )
{
if (loopCount % 2 == 0)
{
pi = pi + ( 4.0/ ((number) * (number+1) * (number+2)) );
}
else
{
pi = pi - ( 4.0 / ((number) * (number+1) * (number+2)) );
}
number = number + 2;
loopCount++;
}
System.out.print( "The Value of Pi in " + term +
" terms is equal to " + pi);
}
}
I am not going to give you code (you can figure it out for yourself, I'm certain), but I'll give you the location for where to look for the problem.
In the negative terms, you are adding 2 to each number multiplied together. However, you are adding 2 to each number in every iteration of the loop: the numberXXX + 2 part should probably just be numberXXX.
You are now also incrementing the numberXXX variables when loopCount is 1. In fact, the if (loopCount == 1) part is unnecessary, since you already initialize pi. You should just remove the if block there and switch the loopCount % 2 == X blocks around.
I'll also give you general advice about things you might want to consider in your code.
You don't need constants like 4.0 to be in a variable. Just replace fourConstant with 4.0.
You don't need to use an else if for the third block: if loopCount % 2 is not 0 it is definitely 1.
loopCount can only get integer values, so it should probably be an int. A double just consumes extra memory (this is not too problematic here, but may be in large programs) and can in some cases lead to errors (too large numbers may cause rounding errors).
You don't need three variables for numberOne, numberTwo and numberThree; they can always be represented as numberOne, numberOne + 1 and numberOne + 2.
You are incrementing the variables numerOne,numberTwo,numberThree in case the loopCount = 1. In this case you should just continue the loop without incrementing this variables. So change this:
if (loopCount == 1 )
{
pi = 3.0;
}
in:
if (loopCount == 1 )
{
pi = 3.0;
loopCount++;
continue;
}
And change this:
pi = pi - ( fourConstant / ((numberOne+2)*(numberTwo+2)*(numberThree+2)));
into:
pi = pi - ( fourConstant / ((numberOne)*(numberTwo)*(numberThree)));
Or you could just initialize loop count to 2 and remove the first if.
Additionally it would be better is loopCount and term were integer variables instead of Double since they are going to hold only integer values.

Number Guessing Game Over Intervals

I have just started my long path to becoming a better coder on CodeChef. People begin with the problems marked 'Easy' and I have done the same.
The Problem
The problem statement defines the following -:
n, where 1 <= n <= 10^9. This is the integer which Johnny is keeping secret.
k, where 1 <= k <= 10^5. For each test case or instance of the game, Johnny provides exactly k hints to Alice.
A hint is of the form op num Yes/No, where -
op is an operator from <, >, =.
num is an integer, again satisfying 1 <= num <= 10^9.
Yes or No are answers to the question: Does the relation n op num hold?
If the answer to the question is correct, Johnny has uttered a truth. Otherwise, he is lying.
Each hint is fed to the program and the program determines whether it is the truth or possibly a lie. My job is to find the minimum possible number of lies.
Now CodeChef's Editorial answer uses the concept of segment trees, which I cannot wrap my head around at all. I was wondering if there is an alternative data structure or method to solve this question, maybe a simpler one, considering it is in the 'Easy' category.
This is what I tried -:
class Solution //Represents a test case.
{
HashSet<SolutionObj> set = new HashSet<SolutionObj>(); //To prevent duplicates.
BigInteger max = new BigInteger("100000000"); //Max range.
BigInteger min = new BigInteger("1"); //Min range.
int lies = 0; //Lies counter.
void addHint(String s)
{
String[] vals = s.split(" ");
set.add(new SolutionObj(vals[0], vals[1], vals[2]));
}
void testHints()
{
for(SolutionObj obj : set)
{
//Given number is not in range. Lie.
if(obj.bg.compareTo(min) == -1 || obj.bg.compareTo(max) == 1)
{
lies++;
continue;
}
if(obj.yesno)
{
if(obj.operator.equals("<"))
{
max = new BigInteger(obj.bg.toString()); //Change max value
}
else if(obj.operator.equals(">"))
{
min = new BigInteger(obj.bg.toString()); //Change min value
}
}
else
{
//Still to think of this portion.
}
}
}
}
class SolutionObj //Represents a single hint.
{
String operator;
BigInteger bg;
boolean yesno;
SolutionObj(String op, String integer, String yesno)
{
operator = op;
bg = new BigInteger(integer);
if(yesno.toLowerCase().equals("yes"))
this.yesno = true;
else
this.yesno = false;
}
#Override
public boolean equals(Object o)
{
if(o instanceof SolutionObj)
{
SolutionObj s = (SolutionObj) o; //Make the cast
if(this.yesno == s.yesno && this.bg.equals(s.bg)
&& this.operator.equals(s.operator))
return true;
}
return false;
}
#Override
public int hashCode()
{
return this.bg.intValue();
}
}
Obviously this partial solution is incorrect, save for the range check that I have done before entering the if(obj.yesno) portion. I was thinking of updating the range according to the hints provided, but that approach has not borne fruit. How should I be approaching this problem, apart from using segment trees?
Consider the following approach, which may be easier to understand. Picture the 1d axis of integers, and place on it the k hints. Every hint can be regarded as '(' or ')' or '=' (greater than, less than or equal, respectively).
Example:
-----(---)-------(--=-----)-----------)
Now, the true value is somewhere on one of the 40 values of this axis, but actually only 8 segments are interesting to check, since anywhere inside a segment the number of true/false hints remains the same.
That means you can scan the hints according to their ordering on the axis, and maintain a counter of the true hints at that point.
In the example above it goes like this:
segment counter
-----------------------
-----( 3
--- 4
)-------( 3
-- 4
= 5 <---maximum
----- 4
)----------- 3
) 2
This algorithm only requires to sort the k hints and then scan them. It's near linear in k (O(k*log k), with no dependance on n), therefore it should have a reasonable running time.
Notes:
1) In practice the hints may have non-distinct positions, so you'll have to handle all hints of the same type on the same position together.
2) If you need to return the minimum set of lies, then you should maintain a set rather than a counter. That shouldn't have an effect on the time complexity if you use a hash set.
Calculate the number of lies if the target number = 1 (store this in a variable lies).
Let target = 1.
Sort and group the statements by their respective values.
Iterate through the statements.
Update target to the current statement group's value. Update lies according to how many of those statements would become either true or false.
Then update target to that value + 1 (Why do this? Consider when you have > 5 and < 7 - 6 may be the best value) and update lies appropriately (skip this step if the next statement group's value is this value).
Return the minimum value for lies.
Running time:
O(k) for the initial calculation.
O(k log k) for the sort.
O(k) for the iteration.
O(k log k) total.
My idea for this problem is similar to how Eyal Schneider view it. Denoting '>' as greater, '<' as less than and '=' as equals, we can sort all the 'hints' by their num and scan through all the interesting points one by one.
For each point, we keep in all the number of '<' and '=' from 0 to that point (in one array called int[]lessAndEqual), number of '>' and '=' from that point onward (in one array called int[]greaterAndEqual). We can easily see that the number of lies in a particular point i is equal to
lessAndEqual[i] + greaterAndEqual[i + 1]
We can easily fill the lessAndEqual and greaterAndEqual arrays by two scan in O(n) and sort all the hints in O(nlogn), which result the time complexity is O(nlogn)
Note: special treatment should be taken for the case when the num in hint is equals. Also notice that the range for num is 10^9, which require us to have some forms of point compression to fit the array into the memory

How do I search for one array whose contents match another?

I have an ArrayList of int arrays that is returning false when I ask if it contains the specified coordinates. It does contain the coordinates I request so it should return TRUE.
Here's my code.
//debug code
for (int i = 0; i < Locations.size(); i++)
{
int[] TestLoc = Locations.get(i);
System.out.print(TestLoc[0] + " " + TestLoc[1] + " " + TestLoc[2] + " == " + Location[0] + " " + Location[1] + " " + Location[2] + "? - ");
if (Location == TestLoc)
{
System.out.println("TRUE");
}
else
{
System.out.println("FALSE");
}
}
//real code
if (Locations.contains(Location))
{
Locations.remove(Location);
}
else
{
System.out.println("FAIL");
}
And output, requesting the coordinates 57, 64, 105 when the list contains 4 coordinates.
56 64 105 == 57 64 105? - FALSE
56 64 106 == 57 64 105? - FALSE
56 64 107 == 57 64 105? - FALSE
57 64 105 == 57 64 105? - FALSE
What gives???
Java's arrays equals are identity equality. You need to create an actual Coordinate class.
Put another way:
int[] c1 = new int[] { 1, 2 };
int[] c2 = new int[] { 1, 2 };
System.out.println(c1.equals(c2)); // prints false
The best would be to get a data class, for instance Coordinate to store your data and override the equals method. Another option, if you just store phone numbers, could be to use strings to reprensent well formatted phone numbers, and the use the equals method of the String class.
Arrays in Java are objects.
When you use the == operator, you are comparing whether Location is the same array as Testloc, which it isn't. What you really want is to compare the values in each array to see if they are equal.
Rather than writing your own, you can use the Arrays.equals() static method to compare the two for equality.
The problem appears to be with the following line:
if (Location == TestLoc)
Presumably, TestLoc is is an array of integers, and Location is also bound to an array.
The test above will only return true if the TestLoc and Location variables both point to the same array instance, and will not return true if those two variables point to different array instances that both happen to have the same integers in the same positions. You're testing "reference equality" above—asking only if these two things are the same thing—as opposed to "value equality," which asks whether two things are equivalent, irrespective of whether they are represented as two distinct objects in the computer's memory space.
Some programming languages lack such a distinction, and some allow one to define new types that are better treated as values—where identity is immaterial—than as entities, where identity may be more important than any would-be value equivalence. Java uses a distinct method—Object#equals()—to query equivalence or value equality of Object instances, while the == operator always does just one thing: it evaluates value equality of any two things, even if those things are object references.
Hence, when comparing two array instances as you are here, both of which are some type of Object, the == operator asks not whether the two things pointed to by those references are equivalent, but rather whether the value of the references themselves are equivalent. If they happen to point to the same target object, they're equivalent, but if they don't, it doesn't matter whether the two distinct target objects would seem similar in value; == returns false because the two target objects are represented by distinct references.
By comparing the arrays with ==, you are checking to see if they are the same array. You would have to loop through each array and check TestLoc[i] == Location[i]. You might be able to use .equals(), I don't recall if java has .equals() for arrays
This works for me:
List<int[]> l = new ArrayList<int[]>();
l.add(new int[] {56, 64, 105});
l.add(new int[] {56, 64, 105});
l.add(new int[] {56, 64, 105});
for (int i = 0; i < l.size(); i++)
{
int[] t = l.get(i);
if (l.get(i) == t)
{
System.out.println("TRUE");
}
else
{
System.out.println("FALSE");
}
}

Floating Point Numbers

This seems like a real simple question but I just to want clear my doubt. I am looking at code which some other developer wrote. There are some calculations involving floating-point numbers.
Example: Float fNotAvlbl = new Float(-99); Why is he creating a new object? What would happen if we do Float fNotAvlbl = -99;(-99 is used as flag here to indicate Not Applicable) Later down the code, we define:
fltValue1 = 0.00f;
fltValue2 = 0.00f;
and populate these two values with a method call which returns float. After that we again convert these two values into Float Objects with:
fltVal1 = new Float(fltValue1);
fltVal2 = new Float(fltValue2);
and than do a comparison if(fltVal1.compareTo(fNotAvailable) == 0) do something.
Is it all because compareTo expects Wrapper Class Objects?
I apologize if this is a real basic question.
Writing Float fNotAvlbl = -99; relies on autoboxing, which has only been added in Java 5, so older code could not use it.
Using -99 as a Float value to mean "Not Applicable" is really, really bad. Either use null or Float.Nan
fltVal1.compareTo(fNotAvailable) == 0 means exactly the same as fltValue1==fltValue2
Comparing float values for strict equality should not be done because it will often fail to work as expected. Read The Float-Point Guide to understand why.
You don't need the wrappers at all
Even if you needed them, using the constructor is not preferred - use Float.valueOf(..) instead.
On the subject of what compareTo() does compared with ==
float a = Float.NaN;
float b = Float.NaN;
System.out.println(a + " == " + b + " is " + (a == b));
System.out.println(a + ".compareTo(" + b + ") is " + ((Float) a).compareTo(b));
float c = -0.0f;
float d = 0.0f;
System.out.println(c + " == " + d + " is " + (c == d));
System.out.println(c + ".compareTo(" + d + ") is " + ((Float) c).compareTo(d));
prints
NaN == NaN is false
NaN.compareTo(NaN) is 0
-0.0 == 0.0 is true
-0.0.compareTo(0.0) is -1
compareTo compares the binary representation (after normalising all NaN values to be the same) As the binary representation for -0.0f and 0.0f are different compareTo does not return 0. There is no special handling in the code other that to use floatToIntBits() and compare that instea dof using ==
The comparison may be using the Float object rather than the built-in float type because of the inherent issues with floating point comparison. Because of the way that floating point numbers are stored on a computer system occasionally the equality comparison between two floating point numbers throws up false negatives. The compareTo from Float may take this into account. The original author possibly at least thought it did.
You can also write your own floating point comparison algorithm that checks for a difference within a reasonable standard deviation for your system. You can also use the method used by equals in Float, which looks at the integer value of the floating point bits for each number.
Note that using Float in and of itself doesn't fix this problem, as the problem is a round-off error in storage.

Categories