Foolin' Around with Fibonacci

I’m working on a challenge related to the Fibonacci sequence. The link to the challenge is here:

The code is below. I realize it is too fat and awkward and am looking to slim it down. I’m sure there’s a method (I’ve thought of consolidating what I’m trying to do in a function and running forEach on it, but I’ve also had this idea that reduce could manage it too…however, I’m unsure of both…which is why I’m here).
Below I have the vague sentiment of a solution, but I’m unsure if the two methods mentioned above address that or if I need to rethink my approach. Maybe just passing a function within a function…I don’t know. I’m kind of stepping all over my brain right now and could really use some to tell me if I am on to something and, if so, which direction I should follow.

(Apologies if this is incomprehensible.)


function tribonacci(signature,n){
  if(n === 0){
  return []
  }
  while(sign.length <= n){
  let sign = signature.slice(0, 3);
  let[x,y,z] = signature;
  let sumOne = x+y+z;
  let sumTwo = sumOne + y + z;
  let sumThree = sumOne + sumTwo + z;
  let sumFour = sumOne + sumTwo + sumThree;
  let sumFive = sumTwo + sumThree + sumFour;
  let sumSix = sumThree + sumFour + sumFive;
  let sumSeven = sumFour + sumFive + sumSix;
  sign.push(sumOne, sumTwo, sumThree, sumFour, sumFive, sumSix, sumSeven)
  return sign;
 }

}

The challenge becomes how can I replicate the above in a loop so that it increments in the manner I wish and then proceeds to push that data into the data cell, so that the while loop can register whether or not its length if equal to n.

This is my attempt at the solution.

function tribonacci(signature, n){
  const sum = arr => arr.reduce((sum, num) => sum + num, 0);
  const tribArr = [...signature];
  let index = 0;
  while (tribArr.length < n) {
    const nextNum = sum(tribArr.slice(index, index++ + 3));
    tribArr.push(nextNum);
  }
  return n > 3 ? tribArr : tribArr.slice(0, n);
}

It could be shortened further by mutating the original signature array passed into the future and then returning a final version. However, I typically don’t like mutating arrays or objects passed in as arguments to a function.

Recursion all the way…

function tribonacci(signature, n){
  if (signature.length > n) {
    return signature.slice(0, n)
  }

  const lastThreeElements = 
    signature[signature.length - 1] + 
    signature[signature.length - 2] + 
    signature[signature.length - 3];
    
  return tribonacci([...signature, lastThreeElements], n)
}

console.log(tribonacci([3,2,1], 10))

Here is mine, quite similar in spirit to @RandellDawson’s

function tribonacci(signature,n){
  //your code here
  const sigCopy = [...signature]
  for(let i=0; i < n-3; i++){
    const newVal = sigCopy[i] + sigCopy[i+1] + sigCopy[i+2]
    sigCopy.push(newVal)
  }
  return n < signature.length ? signature.slice(0,n) : sigCopy
}

Hi Randall,
I had the most trouble understanding your solution but I found it the most intriguing. I spent some time with it and I wonder if you’d look at my comments below from where I attempted it and then tried to explain it.

If you wouldn’t mind, I’d like to know if I’m correctly understanding the logic behind everything being performed in this code. Thank you again.

function tribonacci(signature,n){
  /*
  1. Assign a function to sum and initialize arr and then further clarify arr by performing a reduce method on it.  
  This configuration will be used later to process data in a manner particular to the instructions of the challenge
  */
  
 //1
  let sum = arr => arr.reduce((mum, num)=>
  mum + num, 0);
  
 /*
 2. Assign the signature perimeter to variable, giving it the spread operator in order to include any number of arguments
 3. The while loop specifies how many of those arguments will be included by indicating the arguments must stop
 when the length of the array is equal to argument "n"
 4. As the while loop runs, the sum function is run on the array that itself has the slice method run on it with intervals
 from index to index incremented by 3. run through the sum function which adds these together and produces the
 sums asked for in the tribonacci sequence.  These sums are pushed into the array above and return no error.
 */
 
  //2
  let newArr = [...signature]
  let index = 0;
  //3
  while(newArr.length < n){
  //4
  const thisNum = sum(newArr.slice(index, index++ + 3));
  newArr.push(thisNum);
  }
  
  /*
  5. If "n" argument is defined otherwise, then redo the slice method assigned to thisNum as whatever
  the "n" argument is as the argument would return in error if attempted in the function created above.
  */
  
//5
return n > 3 ? newArr : newArr.slice(0, n)
  
}

@bananahair You have rewritten what I originally wrote for your #1 above. The first line of my function simply creates a function which iterates through the elements in an array and returns the sum of those elements.

The #2 is simply making use of the spread operator to create a copy of the original signature array.

#3 The while loop will keep going until the number of elements in newArr is less than the n.

#5 If n is greater than 3 return newArr. Why? Because if n is greater than 3, the while loop has created the desired final array. If n is less than or equal to 3, then return the first up to (but not including) the nth element of newArr.