Search code examples
javarecursionjava-8backtrackingrecursive-backtracking

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);
    }

Solution

  • Your code never does.

    Recursive algorithms pretty much all boil down to this exact same style:

    1. 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.

    2. 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.

    3. 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.