Infinite loop with do-while condition - java

i'm doing an easy exercise for school, everything work except for this method. i want to insert some teams in a vector, but the array "serie" can only be A or B, upper or lower. I check with the debug and the while condition doens't work even if serie[i]=a.
public static void popolamento(String squadre[], char serie[], int punti[]) {
Scanner in= new Scanner(System.in);
for (int i=0;i<punti.length;i++) {
System.out.println("How many teams?");
squadre[i]=in.next();
do {
serie[i]=in.next().charAt(0);
System.out.println(serie[i]);
}
while (serie[i]!='a' || serie[i]!='A' || serie[i]!='b' || serie[i]!='B');
punti[i]=in.nextInt();
}
System.out.println("teams entered correctly ");}

The condition
(X != a || X != b || X != c || X != d)
should have been
(X != a && X != b && X != c && X != d)
Such a pattern is very likely an error, as to fail, all terms must fail
When X == u (X != u fails) then X != v holds (different cases assumed), hence always true.
If you read something like this, you know it is in 99.9% an error.

Related

How do I break out of this recursive call?

I am a newbie to recursion and I am still learning it, so please tolerate my poor logic if it is bad. I have this function which has 5 parameters a,b,c,x,y. so what I essentially want to do is take an element out of either of these variables and add it to the other to finally get x , y. I want to try out this by myself and I have nearly done it, only i wanted to ask if there's any way i could get out of this recursive call, once I get the answer as "YES".
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String in = sc.nextLine();
int[] input = new int[10];
for(int i=0; i < 10; i=i+2) {
input[i] = Integer.parseInt(String.valueOf(in.charAt(i)));
}
int A = input[0];
int B = input[2];
int C = input[4];
int X = input[6];
int Y = input[8];
persistent(A,B,C,X,Y);
}
private static void persistent(int a, int b, int c, int x, int y) {
if(a == 0 || b == 0 || c == 0) {
if((a == x && b == y) && (b == x && a == y)) {
System.out.println("YES");
}
else if((b == x && c == y) || (c == x && b == y)) {
System.out.println("YES");
}
else if((a == x && c == y) && (c == x && a == y)) {
System.out.println("YES");
}
else {
return;
}
}
persistent(a-1,b+1,c,x,y);
persistent(a-1,b,c+1,x,y);
persistent(a+1,b-1,c,x,y);
persistent(a,b-1,c+1,x,y);
persistent(a+1,b,c-1,x,y);
persistent(a,b+1,c-1,x,y);
}
Your code never does.
Recursive algorithms pretty much all boil down to this exact same style:
First, check if some edge case has been reached (generally, the very simplest case). In this case, return immediately - do not recurse. By tautology, if the answer is so easy you can just give it without needing to recurse, that defines 'edge case' / 'simple case'. There must be at least one such case, or a recursive algorithm cannot work.
Otherwise, provide your answer and feel free to employ as many recursive calls as you prefer, but every single last one of those calls must be simpler, defined by the idea that it is strictly closer to that simple case as mentioned in 1.
All state is conveyed via parameters. It is common to have a private helper method that does the actual work which has a bunch of extra parameters, and the public API that is a one-liner that calls the helper, providing initial values for those extra parameters. Only if you have no such state can you omit this one.
Your code isn't doing this. There is a simple case, which is if a or b or c is 0, but your 6 recursive calls are not clearly moving towards simplicity.
The fix is not obvious. Your algorithm cannot work as written and cannot be fixed without considerably rethinking it.
Hopefully the above will help you: Your recursive calls need to become simpler somehow, guaranteed. Right now it's not guaranteed: Yes, every call is moving one of the 3 numbers closer to the edge case (be 0), but there is no clear flow: If I call your code with, say, 3/4/5 as arguments, then it makes recurisve calls with 2/5/5, 2/4/6, etcetera. That first call (2/5/5) is not moving guaranteed closer to the edge case, because as part of its call stack, it'll be doing 3/4/5 again.

Color Game (Counter Loop not running)

I've been trying to figure out for the life of me why my counter loop isn't running. I have this snippet of my code that will not run even when I qualify the requirements of it being that (counter>=10). It should run the line saying that I lost the Game but it won't do so regardless. I initially thought it was because the counter was within the loop and since it'll keep going it won't ever meet the condition but even then it still won't go. My apologize if its not the best looking code far as spacing goes I'm still new to coding
void draw ()
{
int name=5, strikes=1;
int [][] scores= new int [name][strikes];
int score1=0;
keyPressed();
{
for (int x=0; x<10; x++)
{
first();
if (key == 'r' || key == 'R')
{
secoend();
}
if (key != 'r' || key != 'R')
{
score1++;
} else if (score1>=10)
{
background(255);
String text="You Lost the Game";
text(text, 411, 90);
}
}
}
}
This if-statement is always true, and so it will never enter the else-branch:
if (key != 'r' || key != 'R')
key can only be one thing so either of those is always true
I think you ment:
if (key != 'r' && key != 'R')
Check your if statements, you're always incrementing score1 because if(key != 'r' || key != 'R') will always be true.

same while loop but putting conditions inside while loop doesn't do what it needs to [duplicate]

This question already has answers here:
Why does non-equality check of one variable against many values always return true?
(3 answers)
Closed 2 years ago.
I have two same while loops, the logic is simple. if the value is 7 or the parameter it should stop. it works with the following method
while(true) {
int value = diceRoll();
if(value ==7 || value == point){
return value;
}
System.out.print(value + " ");
}
But with the below method, it doesn't do what it needs too. But it's pretty much the same as the above method.
public static int secondStage(int point) {
int x = 0;
while((diceRoll() != 7) || (diceRoll() != point)) {
System.out.print(diceRoll() + " ");
x= diceRoll();
}
return x;
}
Two primary issues with your second while condition.
You should be using an and operator instead of an or for the
boolean expression to evaluate correctly.
Too many lines of code containing diceRoll(). You can achieve
the purpose by just one call in a given iteration.
Replace your while condition
while((diceRoll() != 7) || (diceRoll() != point))
with
while(x != 7 && x != point)
Overall,
while(x != 7 && x != point) {
x = diceRoll();
System.out.print(x + " ");
}
should work.
I second #DavidZimmerman's comment.
Having multiple diceRoll calls in your while condition may produce some hefty logic bugs. Each of those calls is potentially getting a different result, so your where clause will not be consistant at all.
To add on to #VHS's answer:
Initialize your variable like you did in your last code block
int x = 0;
Take diceRoll out of your where clause as such and call diceRoll() like you have been:
where (x != 7 && x != point) {
// do work
x = diceRoll();
}

Best DRY if statement?

Let's say I want to compare a bunch of variables to one static variable, normally I would do it like this:
int w = 0;
int x = 1;
int y = 1;
int z = 2;
if(w == x || w == y || w == z){/*more code here*/}
But that can get extremely long and doesn't seem necessary, are there any ways to do something more like:
if(w == (x || y || z)){/*more code here*/}
I would like to think that there is a way to do it like this.
Instead of:
if(w == x || w == y || w == z)
you can do:
if(Arrays.asList(x, y, z).contains(w))
Though there is an answer accepted, I would want to share my ways too:
Method 1 is similar to the accepted answer. However, instead of using List, I use a Set. In such case, it may be even faster than doing == individually if there are lots of values to check against:
// make it a static final member if semantically possible
Set<Integer> ALL_VALUES = new HashSet<Integer>(Arrays.asList(a,b,c,d,e,f,g,h));
//.....
if (ALL_VALUES.contains(w)) {
//... do something
}
Method 2 is to write a little utility function, something like
public static <T> boolean sameAsAny(T value, T... possibleValues) {
for (T p : possibleValues) {
if (value == p) {
return true;
}
}
return false;
}
with such util you can do something like:
if (sameAsAny(w, x, y, z))
You might prefer to format it like this :
if(w == x ||
w == y ||
w == z)
I find it helps break up the conditions and makes it easier to read.
That is not allowed in Java. But you could look into some rules based engines e.g drools.

Using the == operator twice in a if statement

Is it okay to do like this in java, does it work?
if (turtles.get(h).getX() == turtles.get(g).getX() == 450) {
//stuff here
}
Basically, i want to check if X is the same value as Y and that value should be 450.
No. What do you expect to happen there?
"a == b" evaluates into a boolean, so "int == (int == int)" would evaluate into "int == boolean", and you cannot compare and int and a boolean.
Besides, what kind of logic are you trying to do here? if ((a == b) && (b == c))?
No, it's not. This is because the result of a == b is a boolean. If you do a == b == c you are first comparing a == b which will return true or false and then comparing that truth value to c.
Not what you want to do, usually!
Note that this trick can work for assignment because the result of a = b is b (the new value of a) which means a = b = c or even (a = b) == c come in useful occasionally.
No. It is the same as (turtles.get(h).getX() == turtles.get(g).getX()) == 450 - "incomparable types". if(turtles.get(h).getX() == 450 && turtles.get(g).getX() == 450).
Or avoid all the less-readable (and error-prone) repetition with a helper method...
public boolean areEqual( int a, int b, int c )
{
return ( a == b ) && ( b == c ) ;
}
That won't work, because the == operator is binary.
And even if it worked sequentially, the first set would return a boolean, which won't work against the integer that follows.
No it won't work, as explained in the other posts. But you could do
if (turtles.get(h).getX() - turtles.get(g).getX() + 450 == 0)

Categories

Resources