Could anyone please tell me what is wrong with the following code. It doesn't show any result.
The integer a,b,c are the side of an right angle triangle.(was solving Project Euler problem 39)
If I use || in place of && , it shows the desired result based on the || condition. But doesn't work with the && condition
public static void main(String[] args) {
int a,b,c;
for (a=1;a<120;a++){
for(b=120;b>0;b--){
c= 120-(a+b);
if (((c) > (a+b)) && ((c*c)==(a*a)+(b*b))){
System.out.println(a + " , " + b +" , " + c);
System.out.println("**************");
}
}
}
}
Quite simply, it's because this expression:
((c) > (a+b))
...never returns true in your example for any valid right angled triangles, and since the && condition requires both operands to evaluate to true, the if statement isn't executed.
You can see this quite clearly if you put in the following lines:
System.out.println("C: " + c);
System.out.println("A+B: " + a+b);
second part of && condition will always be false if first it true. if c > (a+b) then c*c > (a+b)*(a+b) => c^2 > a^2 + b^2 + 2ab then c^2 != a^2 + b^2
Isn't a+b always 121? making c always -1, making c > a+b an illogical comparison? Just what are you attempting to do here?
Anyway, add some System.outs after each { so you know what is happening.
Also add System.out.println( c + " " + a + " " + b + " " + (a+b) + " " + (c*c) + " " + ((a*a)+(b*b))); to see all the parameters in your comparison to make sure you get what you expect before the if itself.
Mathematically both this conditions will never be true that is why && results into false and || works as one of the condition is true in a situation.
(c > (a+b)) && (c*c==(a*a)+(b*b))
If a number is greater than sum of two number then square of the number will be also greater then sum of square of two numbers.
try this
int a,b,c;
for (a=1;a<120;a++) {
for(b=120;b>0;b--){
c= 120-(a+b);
System.out.println(c+">"+(a+b)+" && "+(c*c)+" == "+((a*a)+(b*b)));
if (((c) > (a+b)) && ((c*c)==(a*a)+(b*b))){
System.out.println(a + " , " + b +" , " + c);
System.out.println("**************");
}
}
}
}
and check yourself
i.e.
-66>186 && 4356 == 17330
-65>185 && 4225 == 17137
-64>184 && 4096 == 16946
-63>183 && 3969 == 16757
-62>182 && 3844 == 16570
-61>181 && 3721 == 16385
-60>180 && 3600 == 16202
-59>179 && 3481 == 16021
-58>178 && 3364 == 15842
...
Related
In doing a lotto checker program, where one of the constraints is to not use loops, or data structures like arrays, lists etc I've written the following piece of code to check if the 3 entries given by the user (draw1, draw2, draw3) are equal to any of the 7 random numbers generated by the program (random1, random2, random3, ...).
if (random1==draw1 || random2==draw1 || random3==draw1 || random4==draw1|| random5==draw1
|| random6==draw1 || random7==draw1)
{
if(random1==draw2 || random2==draw2 || random3==draw2 || random4==draw2|| random5==draw2
|| random6==draw2 || random7==draw2)
{
if(random1==draw3 || random2==draw3 || random3==draw3 || random4==draw3|| random5==draw3
|| random6==draw3 || random7==draw3)
{
str = str +'\n' + "The following 3 matches were found:" +'\n'+ draw1 + " " + draw2
+ " " + draw3 ;
}else
{
str = str + '\n' + "The following 2 matches were found:" + '\n' + draw1 + " " + draw2;
}
}else if (random1==draw3 || random2==draw3 || random3==draw3 || random4==draw3|| random5==draw3
|| random6==draw3 || random7==draw3)
{
str = str + '\n' + "The following 2 matches were found:" + '\n' + draw1 + " " + draw3 ;
}
else
{
str = str + '\n' + "The following 1 matches were found:" + '\n' + draw1;
}
}else if (random1==draw2 || random2==draw2 || random3==draw2 || random4==draw2|| random5==draw2
|| random6==draw2 || random7==draw2)
{
if(random1==draw3 || random2==draw3 || random3==draw3 || random4==draw3|| random5==draw3
|| random6==draw3 || random7==draw3)
{
str = str + '\n' + "The following 2 matches were found:" + '\n' + draw2 + " " + draw3;
}
else
{
str = str + '\n' + "The following 1 matches were found:" + '\n' + draw2;
}
}
else if (random1==draw3 || random2==draw3 || random3==draw3 || random4==draw3|| random5==draw3
|| random6==draw3 || random7==draw3)
{
str = str + '\n' + "The following 1 matches were found:" + '\n' + draw3;
}
else
{
str = str + '\n' + "The following 0 matches were found:" ;
}
How can I go about optimizing this and most importantly will the optimization only increase readability or will it contribute to the efficiency of the program?
Use sets, this will improve readabilty.
Set<Integer> luckyNumbers = new HashSet<>();
//Add your numbers to the set
//Integer i = ...
//luckyNumbers.add(i);
Set<Integer> drawNumbers = new HashSet<>();
//Integer i = ...
//drawNumbers.add(i);
Set<Integer> matchNumbers = new HashSet<>(luckyNumbers);
matchNumbers.retainAll(drawNumbers);
//In matchNumbers will be the intersection of the previous sets.
//There you can get the size of the intersection set or its content to show the
//matches
If you want to use a loop for this part you can do something like this:
System.out.println("Number of matches: " + matchNumbers.size());
for(Integer matchNumber : matchNumbers){
System.out.println("Match number: " + matchNumber);
}
Try this.
static boolean equalsAny(int base, int... comparisons) {
for (int c : comparisons)
if (base == c)
return true;
return false;
}
and you can rewrite
if (random1 == draw1 || random2 == draw1 || random3 == draw1 || random4 == draw1 || random5 == draw1
|| random6 == draw1 || random7 == draw1) {
to
if (equalsAny(draw1, random1, random2, random3, random4, random5, random6, random7)) {
So I'm practicing java currently, I'm a beginner and I try to explain all the examples that I code so I can understand how and why things are like that. I understand the concept of recursion but I came across this problem when I tried to explain this code:
import java.util.Scanner;
public class JavaExample {
public static void main(String[] args) {
String str;
System.out.println("Enter your username: ");
Scanner scanner = new Scanner(System.in);
str = scanner.nextLine();
scanner.close();
String reversed = reverseString(str);
System.out.println("The reversed string is: " + reversed);
}
public static String reverseString(String str)
{
if (str.isEmpty())
return str;
//Calling Function Recursively
return reverseString(str.substring(1)) + str.charAt(0);
}
}
With my knowledge so far about recursion, I tried to explain it like this.
Let's have for example a string "Petar":
reverseString(etar)+P
reverseString((tar)+etar)+P
reverseString((ar)+tar+etar)+P
reverseString((r)+ar+tar+etar)+P
-----------------------------------
r+ar+tar+etar+P
I noticed that the right answer is the first character from every individual piece, so I must be close.
Thank you for your time and I'm sorry if I didn't express myself clearly, I'm from Europe (sry bad inglish).
You doing good for first line reverseString(etar)+P you keep at the end only the *first char**, just do the same for next lines
put first char at the end
send the rest to the method
reverseString(etar)+P
reverseString(tar) +e+P
reverseString(ar) +t+e+P
reverseString(r) +a+t+e+P
reverseString('') +r+a+t+e+P // stops when empty string is passed
You got the first call right but the others were a bit off. In each recursive call you return the the string with the first character at the end instead of the begining. Thus, the recursion looks something like this:
reverseString("Petar")
return reverseString("etar") + "P"
return reverseString("tar") + "e"
return reverseString("ar") + "t"
return reverseString("r") + "a"
return reverseString("") + "r"
return ""
So the function will return: (((((("")+"r")+"a")+"t")+"e")+"P"), which is "rateP".
It should become clear when start with the simplest possible example: the empty string and string of size 1. Then substituting arguments of each call, to make it more obvious:
// string.isEmpty() is true, so the empty string is returned immediately
reverse("") -> ""
reverse("a") -> reverse("") + 'a' -> ("") + 'a' -> "a"
These are the trivial examples, let's try it with longer strings:
reverse("ab") -> reverse("b") + 'a'
reverse("abc") -> reverse("bc") + 'a'
-> (reverse("c") + 'b') + 'a'
-> ((reverse("") + 'c') + 'b') + 'a'
-> ((("") + 'c') + 'b') + 'a'
-> "cba"
The general pattern should be clear now. For the sake of completeness, let's manually "unroll" the recursive calls for a 4 character string:
reverse("abcd") -> reverse("bcd") + 'a'
-> (reverse("cd") + 'b') + 'a'
-> ((reverse("d") + 'c') + 'b') + 'a'
-> (((reverse("") + 'd') + 'c') + 'b') + 'a'
-> (((("") + 'd') + 'c') + 'b') + 'a'
-> "dcba"
It works like this:
reverseString("Peter") =
reverseString("eter") + P =
(reverseString("ter") + e) + P =
((reverseString("er") + t) + e) + P =
(((reverseString("r") + e) + t) + e) + P =
((((reverseString("") + r) + e) + t) + e) + P =
(((("" + r) + e) + t) + e) + P =
((((r) + e) + t) + e) + P =
(((r + e) + t) + e) + P =
(((re) + t) + e) + P =
((re + t) + e) + P =
((ret) + e) + P =
(ret + e) + P =
(rete) + P =
rete + P =
reteP
On your example when your function reaches only one character like
Peter when it becomes only "P"
and the string is not empty you call
substring(1)
Which calls an index out of the range while the string only have P on index 0 and none on index 1
You have to put a base case that checks if the string length is equal to 1 or less
As I study recursive algorithms that code below:
String n = starString(3);
System.out.print(n);
} public static String starString(int n){
if(n < 0) {
throw new IllegalArgumentException();
}else if(n == 0) {
return "*";
}else{
return starString(n - 1) + starString(n - 1);
}
I think code will working look like below
String n = starString(3); //Value is 3 then send 3 to function
so it goes to the else condition 3 times, right?
starString(3 - 1) + starString(3 - 1); //Its return is "**"
starString(2 - 1) + starString(2 - 1); //Its return is "**"
starString(1 - 1) + starString(1 - 1); //Its return is "**"
I think that the result should look like this --> ****** //6 items
but the program shows the following instead --> ******** //8 items
Can someone clarify why this is?
When you call starString(3), it returns:
starString(2) + starString(2)
The above expression expands to become (this is where you got it wrong):
(starString(1) + starString(1)) + (starString(1) + starString(1))
Then each of those calls expand to become:
((starString(0) + starString(0)) + (starString(0) + starString(0))) + ((starString(0) + starString(0)) + (starString(0) + starString(0)))
Here's a formatted version of the above:
(
(starString(0) + starString(0))
+
(starString(0) + starString(0))
)
+
(
(starString(0) + starString(0))
+
(starString(0) + starString(0))
)
The outer most bracket is the starString(2) call. The inner bracket is the starString(1) call.
As you can see, there are 8 calls to starString, so 8 *s.
String literal1 = "java";
String object = new String("java");
String literal2 = "java";
System.out.println("result 1 = " + (literal1 == object) );
System.out.println("result 2 = " + literal1.equals(object));
System.out.println("result 3 = " + literal1 == object);
System.out.println("result 4 = " + literal1.equals(object));
System.out.println("result 5 = " + literal1 == literal2);
System.out.println("result 6 = " + literal1.equals(literal2));
Expected output
result 1 = false
result 2 = true
result 3 = false
result 4 = true
result 5 = false
result 6 = true
output obtained
result 1 = false
result 2 = true
false
result 4 = true
false
result 6 = true
When this line
System.out.println("result 5 = " + literal1 == literal2);
is changed to
System.out.println("result 5 = " + (literal1 == literal2));
Output
result 5 = true
Could anyone please explain why this is happening?
It happens because expressions are evaluated left-to-right so it will first concatenate your string (i.e. "result 3 = " + literal1) and then check for truthiness (i.e. == object), hence printing only false because the result of the concatenation is not of the same value as object.
In the first (and last) example ("result 1 = " + (literal1 == object)) you direct the default evaluation with brackets forcing (literal == object) to evaluate separately before the concatenation which is why it prints false only for that evaluation, concatenated with the string preceding it.
TLDR: it's precedence, not left-to-right
Java does have a rule that operands are evaluated left-to-right, but that has no effect here.
Also in Java all binary (meaning two-operand, not bitwise) operators other than assignment are left-associative, but that does not apply here because associativity only matters when operators have the same precedence.
What matters here is that + has higher precedence than == so as VietDD says
System.out.println("result 5 = " + literal1 == literal2);
# is equivalent to
System.out.println(("result 5 = " + literal1) == literal2);
# which is false because they aren't the same object
which happens to be the same as grouping to the left.
But if we consider instead
System.out.println(literal1 == literal2 + " is result 5!");
# THAT is equivalent to
System.out.println(literal1 == (literal2 + " is result 5!"));
# ditto
which happens to be the same as grouping to the right.
System.out.println("result 3 = " + literal1 == object);
System.out.println("result 5 = " + literal1 == literal2);
is equivalent to
System.out.println( ( "result 3 = " + literal1 ) == object);
System.out.println( ( "result 5 = " + literal1 ) == literal2);
It's String Concatenation
The expression is evaluated left to right.
If either operand is a String, + means concatenation
You can try this :
System.out.println( 1 + 2 + "3");
Output :
33
1 + 2 = 3
3 + "3" = "33"
And
System.out.println( "1" + 2 + 3);
Output:
123
"1" + 2 = "12"
"12" + 3 = "123
public void compareTo(String lname1, String lname2) {
/* Note to self: Using this method is case sensitive, because
it only prints if names are found in the array. And those names
are case sensitive inside the array, even though I'm using the
CompareTo method from java's String
class which is NOT inherently case sensitive. ???????? */
boolean foundContact = false;
for(int i = 0; i < arrayOfPersons.size(); i++){
if(arrayOfPersons.get(i).getFname().equals(lname1) && (arrayOfPersons.get(i).getFname().equals(lname2))) {
lname1.compareTo(lname2);
foundContact = true;
}
}
if (foundContact == false)
System.out.println("This option is case sensitive. Check your spelling and try again. Otherwise these contacts do not exist.");
if(lname1.compareTo(lname2) < 0)
System.out.println(lname1 + " comes after " + lname2 + " .");
if(lname1.compareTo(lname2) == 0)
System.out.println(lname1 + " are equal " + lname2 + ".");
if(lname1.compareTo(lname2) > 0)
System.out.println(lname1 + " comes before " + lname2 + " .");
}
case 6:
System.out.println("Enter last name #1:");
String lname3 = scnr.next();
System.out.println("Enter last name #2:");
String lname4 = scnr.next();
Necronomicon.compareTo(lname3, lname4);
break;
// This case is from my main and shows how I use the compareTo method. Just one of many options to my address book.
I created an address book. One of the requirements for my address book is to compare two people by last name. This is the method I wrote to accomplish that goal. However, it's case sensitive when used, so I tried writing a warning to the user.
But the warning prints regardless of whether the contacts are found in the arrayOfPersons. So I think that my boolean is not updating correctly or the way I'm checking to see if the two names exist in the persons array is wrong? Is that right?
Have you tried doing like this ?
boolean foundlname1 = false,foundlname2 = false;
for(int i = 0; i < arrayOfPersons.size(); i++)
{
if(arrayOfPersons.get(i).getFname().equals(lname1) && !foundlname1)
foundlanme1 = true;
if(arrayOfPersons.get(i).getFname().equals(lname2) && !foundlname2)
foundlanme2 = true;
if(foundlanme1 && foundlanme2)
{
foundContact = true;
break;
}
}
if (foundContact == false)
System.out.println("This option is case sensitive. Check your spelling and try again. Otherwise these contacts do not exist.");
else if(lname1.compareToIgnoreCase(lname2) > 0)
System.out.println(lname1 + " comes after " + lname2 + " .");
else if(lname1.compareToIgnoreCase(lname2) == 0)
System.out.println(lname1 + " are equal " + lname2 + ".");
else
System.out.println(lname1 + " comes before " + lname2 + " .");
}
Your if statement in the for loop will never be true unless lname1 and lname2 are equals. I don't know if what you did is what you wanted to do. You can do like this which is similar to your code you already have:
In the compareTo method check if the arrayOfPersons contains those two Persons
if(arrayOfPersons.contains(Person1) && arrayOfPersons.contains(Person2)
and then compare lname1 and lname2 like you did with your last three if statements
Note that to use the contains method you need to ovverride in your Person class the equals method
public void compareTo(String lname1, String lname2) {
boolean foundContact1 = false;
boolean foundContact2 = false;
for(int i = 0; i < arrayOfPersons.size(); i++){
if(arrayOfPersons.get(i).getLname().equals(lname1)) {
foundContact1 = true;
}
}
for(int i = 0; i < arrayOfPersons.size(); i++){
if(arrayOfPersons.get(i).getLname().equals(lname2)) {
foundContact2 = true;
}
}
if (foundContact1 && foundContact2 == false)
System.out.println("This option is case sensitive. Check your spelling and try again. Otherwise these contacts do not exist.");
if(foundContact1 && foundContact2 == true) {
if(lname1.compareTo(lname2) < 0)
System.out.println(lname1 + " comes after " + lname2 + " .");
else if(lname1.compareTo(lname2) == 0)
System.out.println(lname1 + " are equal " + lname2 + ".");
else if(lname1.compareTo(lname2) > 0)
System.out.println(lname1 + " comes before " + lname2 + " .");
}
}
I figured it out. This is what I was looking for. Thanks for the pointers everybody. Similar to solution to what Shreshta proposed, just had to modify his logic a little bit.