1

Given a number the program should return a sequence of operations using only *3 or +5 to get to the number, thus there are two paths to take. How do this program know which function call to make when it calls itself? And how does it know how many times to call each path. In other words I dont understand how the OR operator is being used to determine which call to find() to use and how many of each.

function findSequence(goal) {
    // we start at 1, and history is a string that will keep track of the operations
    function find(start, history) {
        // case when start and goal is 1.
        if (start == goal)
            return history; // return string containg 1
        // case when we build start past what we needed
        else if (start > goal)
            return null;
        else
            // Dont understand this part!
            return find(start + 5, "(" + history + " + 5)") ||
                find(start * 3, "(" + history + " * 3)");
    }
    return find(1, "1");
}

document.write(findSequence(13));
Oleg
  • 9,341
  • 2
  • 43
  • 58
DEdesigns57
  • 361
  • 1
  • 5
  • 13
  • There is a similar question here http://stackoverflow.com/questions/2966430/why-does-javascripts-or-return-a-value-other-than-true-false which has some useful information. – Tim B James Mar 25 '13 at 16:39

2 Answers2

3

The || operator checks the truth value of the left operand. Interestingly, the || expression does not evaluate to true or false. If the truth value is true, the expression evaluates to that left operand. If it is not, then it evaluates to the right operand. Example:

> 5 || 10
5
> 5 || 0
5
> 0 || 10
10
> 0 || undefined
undefined

Thus a || b is actually equivalent to a ? a : b. Similarly, a && b is actually equivalent to a ? b : a:

> 0 && 10
0
> 0 && undefined
0
> 5 && 10
10
> 5 && undefined
undefined

Truth value for non-boolean values is determined in the JavaScript specification:

  • Undefined -> False
  • Null -> False
  • String -> False if empty string, True otherwise
  • Object > True

EDIT: Oh, as mattedgod points out, as soon as the expression evaluates to a result, the rest of the expression does not get evaluated at all. For example:

> function fail() { throw "I failed!"; }
> fail()
XXX "I failed!"
> 5 || fail()
5
> 0 && fail()
0

No failure happens in the above cases, but in the following they do:

> 0 || fail()
XXX "I failed!"
> 5 && fail()
XXX "I failed!"

Thus, if you have two calls to find() like find(...) || find(...), if the result of the first call has a true truth value, then its result will be returned and the second one won't execute at all. If the result of the first call has a false truth value, then the second call will execute and the expression evaluates to whatever that result is.

Claudiu
  • 224,032
  • 165
  • 485
  • 680
2

This is relying on a property of JavaScript (and many other languages) called "short-circuiting."

If you think about it, if you are evaluating something to be true and it is A || B, if A is true, then the whole expression will be true, there's no sense checking B. The opposite is true for &&, if A is false and you are evaluating A && B, the whole expression is false so no sense to bother with B.

In your example, if the first call to find succeeds, it will not execute the second one. However, if the first call does not succeed (I am guessing it returns false or null or something that evaluates to JS false), the second call will get executed.

Matt Dodge
  • 10,833
  • 7
  • 38
  • 58