Break Iteration of Java loop with control flow with a recursive method - java

My attempt at recursion by trying to solve the monkey/coconut/sailor problem.
Im having issues with my for loop stopping. It just iterates though and im unsure where I went wrong.
in my 3 test cases the method testCoconuts returns the values I would like, however my loop will iterate until the last number, even if the true values are sent through the loop.
im sure its my booleans, but i havent been able to figure out what im doing wrong.
public class Test {
public static boolean testCoconuts(int s, int sr, int c){
if (c % s == 1 && sr > 0) {
Test.testCoconuts(s, sr - 1, c - (c/s) - 1);
}
else if (c % s != 1) {
return false;
}
else if (sr == 0) {
System.out.println("solved");
return true; //returns true in all 3 test cases below
}
return false;
}
public static void main(String[] args) {
//int s and sr must me entered into the test program
//as the same number, ex s= 2, sr = 2
int sailors = 3;
Test.testCoconuts(2, 2, 7); //will print solved
Test.testCoconuts(3, 3, 79); //will print solved
Test.testCoconuts(4,4,1021); //will print solved
for (int testNuts = 1; testNuts < 100; testNuts++) {
if (Test.testCoconuts(sailors, sailors, testNuts)==true) {
System.out.println("solved!");
break;
}
else {
System.out.println(testNuts);
System.out.println("next iteration");
System.out.println(testNuts);
}
}
}
}

The for-loop will run until the testCoconouts method equals true.
Now if you take a look at the method, there are four possible outcomes:
if (c % s == 1 && sr > 0)
else if (c % s != 1)
else if (sr == 0)
none of the above was satisfied
However, only in the last three of them have you explicitly stated what value the method should return.
So - in the first outcome, since nothing else is said, the method will always return false as stated outside of the if-statements. I assume you want to return the result from the recursion itself, right?
Try changing the first if-statement like this and see what happens :)
if (c % s == 1 && sr > 0) {
boolean result = Test.testCoconuts(s, sr - 1, c - (c/s) - 1);
return result;
}
(Could be done in a one-liner without the variable result, but I splitted it up for clarity)

Please remember that you call your function recursively and sending a return back to the previous function call, not to the main
Here is a solution:
public class Test {
public static boolean testCoconuts(int s, int sr, int c){
boolean flag = false;
if (c % s == 1 && sr > 0){
flag = Test.testCoconuts(s, sr - 1, c - (c/s) - 1);
}
else if (c % s != 1){
return flag;
}
else if (sr == 0){
System.out.println("solved");
return true; //returns true in all 3 test cases below
}
return flag;
}
public static void main(String[] args){
//int s and sr must me entered into the test program
//as the same number, ex s= 2, sr = 2
int sailors = 3;
//Test.testCoconuts(2, 2, 7); //will print solved
//Test.testCoconuts(3, 3, 79); //will print solved
//Test.testCoconuts(4,4,1021); //will print solved
for (int testNuts = 1; testNuts < 100; testNuts++){
boolean flag = Test.testCoconuts(sailors, sailors, testNuts);
System.out.println(testNuts);
if (flag==true){
System.out.println("solved!");
break;
}
else{
System.out.println(testNuts);
System.out.println("next iteration");
System.out.println(testNuts);
}
}
}
}

Related

Method won't run because it returns no string

I'm creating a battleship game where a ship occupies 3 cells and you have to guess which cell. Once they guess it you return "hit" and if not you return "miss". Once they hit all 3 you return "kill". I've written the code but it states I still haven't returned a string.
public class SimpleBattleShip{
int[] shipCoordinates;
int numOfHits;
String updateStatus(int guess){
for(int i=0;i<shipCoordinates.length;i++){
if(guess == shipCoordinates[i]){
numOfHits++;
if(numOfHits ==3){
return "kill";
}else{
return "hit";
}
}else{
return "miss";
}
}
}
}
Have you tried just separating the NumberofHits If statement from the for loop. The problem may be the for loop iterating the whole 'hit check' for each value of 'i' which may cause it to put up false values before tallying the full amount of hits.
I've tried throwing in an else if to maybe tighten the parameters. turn it back to else if you want (this is for hit & miss).
public class SimpleBattleShip {
int[] shipCoordinates;
int numOfHits;
String updateStatus(int guess) {
for (int i = 0; i < shipCoordinates.length; i++) {
if (guess == shipCoordinates[i]) {
numOfHits++;
}
}
if (numOfHits == 3) {
return "kill";
} else if (numOfHits < 3 && numOfHits >= 1) {
return "hit";
} else {
return "miss";
}
}
}

Method with boolean return type not working inside main()

I had static method which is to find out prime number and it is working fine but the same method i am trying to keep inside main method it is throwing errors by stating illegal modifiers for parameter and void method does not return value
the same code is working fine outside of main method, any one plz sugggest me why it is not working in main() . Thanks ..!!
My method
public static boolean isPrimeNumber(int number) {
if (number == 2 || number == 3) {
return true;
}
if (number % 2 == 0) {
return false;
}
int sqrt = (int) Math.sqrt(number) + 1;
for (int i = 3; i < sqrt; i += 2) {
if (number % i == 0) {
return false;
}
}
return true;
}
Inside main() with lot of error message
inside main
Solution
Thanks Logan --- need to add methods outside main method
my working code is added below
public class Squar {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
Squar s = new Squar();
//System.out.println(s.isPrime(num));
scan.close();
System.out.println("M2 "+s.isPrimeNumber(num));
}
public boolean isPrimeNumber(int number) {
if (number == 2 || number == 3) {
return true;
}
if (number % 2 == 0) {
return false;
}
int sqrt = (int) Math.sqrt(number) + 1;
for (int i = 3; i < sqrt; i += 2) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
You are getting this error because Java does not support nested function.
You are implementing method inside other method, that is not possible. to nest methods use lambdas in java 8.
have a look at Can methods in java be nested and what is the effect? [closed]

How can I optimize this code (return statements)?

So while I was typing this question, I found a workaround for a "missing return statement" error. But I still don't think this is the proper way of doing it. As you can see I have some nested if statements. I want both conditions to be met before returning anything, but I had to place the return statements outside of the nested if statements. If the last condition isn't met doubt this should cause much problem since an empty string will be returned, but I just feel as if this isn't the best way of going about doing things.
1st Edit: with my current update, i'm still missing a return statement. I could do the same fix i applied but I feel as if it is innapropriate.
public String findProtein(String dna) {
int start = dna.indexOf("atg");
int stop1 = dna.indexOf("tag", start + 3);
int stop2 = dna.indexOf("tga", start + 3);
int stop3 = dna.indexOf("taa", start + 3);
String subStr1 = dna.substring(start, stop1);
String subStr2 = dna.substring(start, stop2);
String subStr3 = dna.substring(start, stop3);
boolean geneFound = false;
if (subStr1.length() % 3 == 0) {
geneFound = true;
return subStr1;
}
if (geneFound == false) {
if (subStr2.length() % 3 == 0) {
geneFound = true;
}
return subStr2;
}
if (geneFound == false) {
if (subStr3.length() % 3 == 0) {
geneFound = true;
}
return subStr3;
}
if (geneFound == false) {
return "";
}
}
2nd Edit: additional code
private void stopCodon(String gene){
//This prints out the last 3 characters of the gene
String stopCodon = gene.substring(gene.length() - 3);
System.out.println(stopCodon);
}
public void testing() {
String a = "ataaactatgttttaaatgt";
String result = findProtein(a);
stopCodon(result);
}
If it were me, I would edit the following logic
if( subStr1.length() % 3 ==0 ){
geneFound = true;
return subStr1;
}
if(geneFound == false){
if(subStr2.length( )% 3 ==0 ){
geneFound = true;
}return subStr2;
}
if(geneFound == false){
if(subStr3.length( )% 3 ==0 ){
geneFound = true;
}
return subStr3;
}
if (geneFound == false){
return "";
}
To the following using else if statements:
if( subStr1.length() % 3 ==0 ){
return subStr1;
} else if (substr2.length()%3==0){
return substr2;
} else if (substr3.length()%3 == 0) {
return substr3;
} else {
return null;
}
I'm also not sure if String subStr1 = dna.substring(start,stop1); is something you want since an Exception will be thrown if the stop codon doesn't exist, but it would be hard to judge without you giving us additional information.
Added
Kind of saw this coming, but if you look at the description for indexOf
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int)
the index of the first occurrence of the character in the character sequence represented by this object, or -1 if the character does not occur.
If you want to check if the substring exists, you check if the index is -1
I'm only gonna go through an example for the first substring
int stop1 = dna.indexOf("tag", start + 3);
if(stop != -1) {
return dna.substring(start, stop1);
}
You should start by checking if the start codon exists at all and return null if it doesn't exist immediately, since locations of stop codons are useless without start codons.
Hopefully this helps
if( subStr1.length() % 3 ==0 ){
geneFound = true;
result = subStr1;
}else if(geneFound == false){
if(subStr2.length( )% 3 ==0 ){
geneFound = true;
}
result = subStr2;
}else if(geneFound == false)
if(subStr3.length( )% 3 ==0 ){
geneFound = true;
}
result = subStr3;
}
if (geneFound == false){
result = "";
}
return result;
result is of type String.
However any one of three if statements will return the value. If not fourth if statement will return the value.
You can assign the result to a variable and return it at the end
Why don't you return something like this ?
public String findProtein(String dna) {
String valueToBeReturned = "";
if(condition 1){
valueToBeReturned = "value1"
}
if(condition 2){
valueToBeReturned = "value2"
}
//Rest of the conditions
return valueToBeReturned; //Finally return the specific value
}
How about remove unnecessary block of code?
if (geneFound == false) {
return "";
}
Since you return a value and the boolean is a local variable, it doesn't really matter if you change the boolean value or not in this code. I really don't see a use for it at the time. I simplified the code following your logic!
public String findProtein(String dna) {
int start = dna.indexOf("atg");
int stop1 = dna.indexOf("tag", start+3);
int stop2 = dna.indexOf("tga",start+3);
int stop3 = dna.indexOf("taa",start+3);
String subStr1 = dna.substring(start,stop1);
String subStr2 = dna.substring(start,stop2);
String subStr3 = dna.substring(start,stop3);
if(subStr1.length() % 3 == 0 ) {
return subStr1;
}
if(subStr2.length() % 3 == 0 ){
return subStr2;
}
if(subStr3.length( )% 3 ==0 ){
return subStr3;
}
return "";
}

Why is my break statement being ignored?

In my method under the if statement:
if (currentLocationX == 0 && currentLocationY == 4)
I have a break statement that should make the program exit out of the while loop and return true for 'answer' and for the method. Yet after some testing it seems that after returning true for 'answer', it goes back into the while loop giving the wrong results int the end. Why is my break statement not doing what it's supposed to? Thank you!
P.S. (this method calls on some other method that were not relevant to mention here)
public boolean solveMaze()
{
boolean answer = false;
int currentLocationX;
int currentLocationY;
//push starting location
pushX(2);
pushY(1);
while((isEmptyX() == false) && (isEmptyY() == false))
{
printMaze();
System.out.println();
currentLocationX = popX();
currentLocationY = popY();
//mark current location as visited
visited(currentLocationX, currentLocationY, maze);
System.out.println("Current Location: " + currentLocationX + ", " + currentLocationY);
if (currentLocationX == 0 && currentLocationY == 4)
{
answer = true;
break;
}
else
{
//push all unvisited OPEN neighbor locations into stack
if (checkEast(currentLocationX, currentLocationY) == 0)
{
pushX(eastX(currentLocationX));
pushY(eastY(currentLocationY));
}
else;
if (checkSouth(currentLocationX, currentLocationY)== 0)
{
pushX(southX(currentLocationX));
pushY(southY(currentLocationY));
}
else;
if (checkWest(currentLocationX, currentLocationY)== 0)
{
pushX(westX(currentLocationX));
pushY(westY(currentLocationY));
}
else;
if (checkNorth(currentLocationX, currentLocationY)== 0)
{
pushX (northX(currentLocationX));
pushY(northY(currentLocationY));
}
else;
}
}
return answer;
}
I wrote out the basic logic of your method as
public static boolean solveMaze() {
boolean answer = false;
int currentLocationX = 0;
int currentLocationY = 4;
while (true) {
if (currentLocationX == 0 && currentLocationY == 4) {
System.out.println("Hit the break");
break;
} else {
System.out.println("Missed the break");
}
}
return answer;
}
and if you execute it you get Hit the break. So your solveMaze() method is fine in terms of breaking out of the loop once it satisfies your if-statement. I would say that if you see your code subsequently going back into the while loop, it must be that solveMaze() was called a second time.

How to Update a Counter for Fibonacci using Recursion?

Here's the deal I want to count the recursive calls for a basic Fibonacci code. I already have it so the values will print out in column format but I don't know how to update the recCounter. I think I have to add recCounter++; Somewhere and I don't know where
public static int recursionFibonacci(int n) {
recCounter = 1;
return fibonacci1(n);
}
public static int fibonacci1(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci1(n-1) + fibonacci1(n-2);
}
}
You should increment the counter every time you call the function:
public static int fibonacci1(int n) {
recCounter++; // <<-- here
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci1(n-1) + fibonacci1(n-2);
}
}

Categories