Search code examples
recursionreturnbooleanterminatecallstack

How to return correct boolean in recursive function?


I know that the general template for recursive functions requires a return statement for each case. Consider this recursive function, which should (but fails to) return true if a given integer list can make 24 through the arithmetic operators (*,/,+,-).

static boolean doArith(List<Double> A, double temp, int start) {
    // base case
    if (start == A.size()) return temp == 24;

    // recursive calls
    for (int op = 0; op < 4; op++) {
        doArith(A,
                arith(temp,op,A.get(start)),
                start+1);
    }

    return false;
}

Through print statements in the base case block, I know for certain my code correctly identifies when 24 has been made. However, it fails to return true when the call stack resolves.

I've tried refactoring the code, even hard coding the for loop into 4 separate calls, but as expected, that didn't work.

(Edit: In response to @Caramiriel comment) I tried rewriting the function as:

static boolean doArith(List<Double> A, double temp, int start) {
    // base case
    if (start == A.size()) return temp == 24;

    boolean b = false;
    // recursive calls
    for (int op = 0; op < 4; op++) {
        b = doArith(A,
                arith(temp,op,A.get(start)),
                start+1);
    }
    return b;
}

But this still returns always false.

How do I get this function to return true the moment it comes across such a case?

Thanks


Solution

  • If the operation that causes the result to be 24, you know the answer is right and need to break from the loop:

    static boolean doArith(List<Double> A, double temp, int start) {
        // base case
        if (start == A.size()) return temp == 24;
    
        // recursive calls
        for (int op = 0; op < 4; op++) {
            boolean b = doArith(A,
                    arith(temp,op,A.get(start)),
                    start+1);
    
            if(b) {
                return true;
            }
        }
    
        return false;
    }
    

    The following code:

    boolean b = false;
    // recursive calls
    for (int op = 0; op < 4; op++) {
        b = doArith(A,
                arith(temp,op,A.get(start)),
                start+1);
    }
    

    just checks for the last case (op = 3).