Replace Loops using Recursion -1 explanation

In the instructions for this it says the following:

However, notice that multiply(arr, n) == multiply(arr, n - 1) * arr[n - 1] . That means you can rewrite multiply in terms of itself and never need to use a loop.

Could somebody please explain how multiply(arr, n) == multiply(arr, n - 1) * arr[n - 1]??

I don’t understand how the -1 appears.

2 Likes

Hello there.

If you have a question about a specific challenge as it relates to your written code for that challenge, just click the Ask for Help button located on the challenge. It will create a new topic with all code you have written and include a link to the challenge also. You will still be able to ask any questions in the post before submitting it to the forum.

Thank you.

The answer to your question is evident in the challenge:

Write a recursive function, sum(arr, n) , that returns the sum of the first n elements of an array arr .

You are summing the first n elements of an array.
Javascript is zero index based. So, if I want to sum the first let n = 1 elements of this array const arr = [2, 3, 4, 5], I need to index into the array arr[n-1]

I hope that helps.

I haven’t written any code yet.

Can you explain in simpler language? I understand that JavaScript is zero index based but if that is the case then I don’t understand how an Array can have a -1 value? Or how the parameter of a function can be n-1 when it is defined as n?

I also don’t understand your explanation. What do let n=1 and const arr mean?

Ah well, it is difficult for me to explain everything from square-one. I assume you have completed all the challenges before this one: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/replace-loops-using-recursion
If not, please do.

Otherwise, let me rephrase what I said: You have this function

function multiply(arr, n) {
    if (n <= 0) {
      return 1;
    } else {
      return multiply(arr, n - 1) * arr[n - 1];
    }
  }

You would use this function by calling it like so (this is an example):

var myArr = [2, 3, 4, 5];
var numberOfElements = 2;
multiply(myArr, numberOfElements);

When this is called, the following will happen:

function multiply(arr, n) {
// Now arr = [2, 3, 4, 5], and n = 2
// n > 0, So this does not run
    if (n <= 0) {
      return 1;
    } else { // The function is called again, but the arguments have changed
      return multiply(arr, n - 1) * arr[n - 1]; // arr[2-1] is the same as arr[1] == 3 (the second element of arr)
    }
  }

Next, this:

function multiply(arr, n) {
// arr = [2, 3, 4, 5];
// n = 2-1
    if (n <= 0) { // This still does not apply
      return 1;
    } else { // This is called again, again with different arguments
      return multiply(arr, n - 1) * arr[n - 1]; // arr[1-1] == arr[0] which is equal to 2 (the first element of arr)
    }
  }

Next this:

function multiply(arr, n) {
// arr does not change...
// n = 2 - 1 - 1 which is equal to 0
    if (n <= 0) { // This is true!
      return 1; // So, 1 is returned...
    } else {
      return multiply(arr, n - 1) * arr[n - 1];
    }
  }

Now, follow everything backwards to get to the original return statement.

I hope this helps. If not, search this forum for posts about recursion, as others have answered with much better responses.

1 Like

Ignore my use of let and const. They are similar to using var, but you will be taught about them in the ES6 section of the curriculum.

Hi - No, I don’t have that function. I have this function:

function multiply(arr, n) {
    var product = 1;
    for (var i = 0; i < n; i++) {
        product *= arr[i];
    }
    return product;
  }

You have posted the next stage. I’m still on the previous one.

The question is how a parameter of ‘n’ is equal to n-1 * arr[n - 1].

In that function, there is no reference to n-1 or arr[n-1].

This function plainly multiplies all of the elements together.
If arr = [2, 3, 4, 5]; and n=2, then that function goes through every element until the 2nd ( nth) element, multiplying them. In this case, the 2nd element is arr[1] which equals 3.

Hi - please look at the challenge page. It clearly states below that function:

However, notice that multiply(arr, n) == multiply(arr, n - 1) * arr[n - 1] .

That is my question.

Well, going off of my last example:

var myArr = [2, 3, 4, 5];
var numberOfElements = 2;
console.log(multiplymyArr, numberOfElements);
// Expected output: 6   (2 x 3)

Now, following this logic:

multiply(myArr, numberOfElements - 1)*myArr[numberOfElements - 1];

The first part:

console.log(multiply([2, 3, 4, 5], 1));
// Expected Output: 2

Second part:

console.log(myArr[1]);
// Expected Output: 3

Therefore:

2 * 3 === 6 === multiply(myArr, numberOfElements - 1)*myArr[numberOfElements - 1];

Hope that helps

Now, following this logic:

multiply(myArr, numberOfElements - 1)*myArr[numberOfElements - 1];

What logic? How do you get the -1!

You put it there…

The whole point of the lesson is to teach recursion. This example is plain product logic:
image

No, the example specifically states that the function is equal to something different. You don’t put a -1 anywhere.

I’m literally asking how one thing equals another thing. I think you’re missing what I’m asking.

I am struggling to understand what is confusing you. If you are referring to this example:

multiply(arr, n) == multiply(arr, n - 1) * arr[n - 1]

Then, I have explained the work through in three different ways. I explained that they are in-fact equal.

What do you mean by this?

I don’t understand your explanations.

In the first explanation you use the wrong function.

In the second you assume that I understand the logic which is exactly what I don’t understand.

In the third you use a completely different format and language which I have no understanding of.

I appreciate that it may well be difficult to explain everything from square one but this is a basic JavaScript course so that is exactly what I need!

Thank you for your perseverance thus far.

Let me start earlier:
This is how you access values inside an array:

var myArr = [2, 3, 4, 5];
// I want to get the number 4
var four = myArr[2] // 4 is the 3rd element of myArr, but
// in JavaScript, you start counting from the number 0. So,
myArr[0] === 2 // For now, === just means 'is really equal'

Another way I could have retrieved the number 4 is:

var myIndex = 3;
var four = myArr[myIndex - 1] // myIndex is 1 too many. So,
// Subtract 1.
// In JS, the mathematical operation myIndex-1 is evaluated first.

Now, let us return to my examples:

multiply(myArr, 2) === 6 // Do you agree?
multiply(myArr, 1) === 2 // Do you agree?
arr[1] === 3 // Do you agree?
// Therefore,
6 === 2 * 3 // Do you agree?

Hi, thanks for trying.

I don’t understand your explanations and I can’t seem to convey what it is that I’m struggling with in this explanation. I’m going to try and learn recursion from somewhere that explains it in another manner. Then I’ll come back and try this when I understand the concept and don’t get confused by a poorly explained example.

I wonder if this is more of an interpretation issue. I don’t have any background in computer science and the last time I did any mathematics was over 10 years ago and I spent most of my time pretending I was anywhere else so perhaps the assumption in FCC that basic concepts are understood is where I’m failing. It does seem to me that the ‘basic’ JS lessons go from zero to hero in a few steps. I flew through the majority of these challenges but have then spent multiple days trying to get through the final half dozen or so.

If you didn’t do all of the 99 preceding lessons, what could explain the difficulty you are having.

Hi - as I make fairly clear in the above comment, I did all of the previous lessons.

You questions are confusing then. You don’t seem to understand indexing?

Do you believe that these two code snippets are equivalent?

var result = 1
for (var i = 0; i < 10; i++) {
  result *= i;
}

and

var result = 1
for (var i = 1; i <= 10; i++) {
  result *= (i - 1);
}

Indexing works the same way:

var result = 1
for (var i = 0; i < 10; i++) {
  result *= myArray[i];
}

and

var result = 1
for (var i = 1; i <= 10; i++) {
  result *= myArray[i - 1];
}

The exercise is asking you to replace a loop like the one given above with recursion. To do so, you need to multiply the last entry in the array, entry n, by the second to last entry, entry n - 1, and so on until you reach entry 0.

That’s likely, I have no other experience of JS. This is my second time through these challenges though.