Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
192 views
in Technique[技术] by (71.8m points)

Javascript recursion from Eloquent Javascript

So this is from the Eloquent Javascript. I am trying to figure out how this code is actually stepped through. So we are trying to find a way to reach the target number by adding either 5 or multiplying by 3, and we start from the number 1. So, essentially, we are trying to find a sequence of such additions and multiplications that produce the target number? For example, the number 13 could be reached by first multiplying by 3 and then adding 5 twice, whereas the number 15 cannot be reached at all.

Here is the code snippet:

function findSolution(target) {
  function find(start, history) {
    if (start == target)
      return history;
    else if (start > target)
      return null;
    else
      return find(start + 5, "(" + history + " + 5)") ||
             find(start * 3, "(" + history + " * 3)");
  }
  return find(1, "1");
}

The result:

console.log(findSolution(24));// → (((1 * 3) + 5) * 3)

Apparently this is what happens when we call findSolution(13):

To better understand how this function produces the effect we’re looking for, let’s look at all the calls to find that are made when searching for a solution for the number 13.

find(1, "1")
  find(6, "(1 + 5)")
    find(11, "((1 + 5) + 5)")
      find(16, "(((1 + 5) + 5) + 5)")
        too big
      find(33, "(((1 + 5) + 5) * 3)")
        too big
    find(18, "((1 + 5) * 3)")
      too big
  find(3, "(1 * 3)")
    find(8, "((1 * 3) + 5)")
      find(13, "(((1 * 3) + 5) + 5)")
        found!

Question:
1) I am confused what happens when we call findSolution(13). How is it that the first line is find (1, "1") when I haven't supplied it either the start or history number? How does the code just step down to line:

return find(1,"1")

How does the code get there?
2) Is this how OR statements operate in recursion? In a recursive check, does Javascript typically explore the first branch of the OR statement before tackling the second branch? Is this line:

find(3, "(1 * 3)")  

only checked after the all of the branches of:

find(6, "(1 + 5)")

fail to return a solution?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

1) If you look at the code, the function "findSolution" is composed of two parts: a method definition "find", and a call to that method "return find(1, "1")". The definition, in itself, won't produce computing unless it is called. So, the first expression that is actually executed is "find(1, "1")". It's the starting point.

2) OR statements are executed in their reading order, so "find(start + 5, ...)" will be first executed, and then only if it does return null (that is, it hasn't find the solution) the next statement "find(start * 3, ...)" is going to be executed. Due to recursion, you can have any number of "+5" exection before a "*3" being executed, depending on the target of course.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...