I'm new to programming and learning about javascript recursion. It's my 5th day with JavaScript and following an online course.
The problem is that I need to sum up first n numbers of entries (first 3 numbers in this case) in an array.
But I'm ending up with sum of all and that also I'm not sure about.
var theArray = [1, 3, 8, 5, 7];
function sum(arr, n) {
if (n <= 0) {
return 1;
} else {
return arr[n - 1] + sum(arr, n - 2);
//assuming n is arr.length and n-1 is hence arr.length-1
}
}
console.log(sum(theArray, 3));
What am I doing wrong?
I checked most people are solving such with reduce method or with for of loop. I didn't learn those yet in the curriculum. But I know 'for loop' but that's good if the numbers are in incremental order I guess. Please explain this problem in my level.
When implementing something recursively, it's a good idea to think about the base condition. It does look like that's where you started, but your logic is flawed. n is the number of elements you would like to sum together. So let's say you want to sum the first n=3 elements of the array [2,3,4,5,6] and get 9. Here are the iterations.
return arr[n-1] + sum(arr, n-1) // arr[2] + sum(arr, 2) === 4 + sum(arr, 2) === 4 + 5
return arr[n-1] + sum(arr, n-1) // arr[1] + sum(arr, 1) === 3 + sum(arr, 2) === 3 + 2
return arr[n-1] // arr[0] === 2 (base case when n is 1)
I didn't solve the problem for you since this is obviously a school exercise, but the point is that the base case and the recursive call that you have are both slightly off.
Array of undetermined length, find the largest sum possible for any 3 consecutive numbers.
[2,0,1,100,200,10,7,2, 300,2,1 0] here 100,200,10 = 310 is the correct answer. Here only the combination of these 3 numbers produces the largest sum.
[2,1,0,20,71 = 0+20+7 = 27 is the answer that you should return.
const findMax = (numberArray) => {
let first = 0;
let second = 1;
let third = 2;
let max = 0;
for(; third < numberArray.length; first++, second++, third++) {
if(max < (numberArray[first] + numberArray[second] + numberArray[third])) {
max = numberArray[first] + numberArray[second] + numberArray[third];
}
}
return max;
}
console.log('Max sum of three consecutive numbers in array ===> ',findMax([2, 0, 100, 200, 10, 7, 2, 300, 2, 10]));
Related
I think I'm having a brain fart, because I can't figure out a simple formula to be able sort a sequence of number into specific order so it can be printed 2 numbers per sheet of paper (one number on one half and second number on second half), so when the printed stack of paper cut in half, separating the numbers, and then these halves put together, the numbers would be in sequence.
So, let's say I have 5 numbers: 3,4,5,6,7, the expected result would be 3,6,4,7,5 or
0,1,2,3,4,5,6,7 would become 0,4,1,5,2,6,3,7
My thought process is:
create a loop from 0 to total number of numbers
if current step is even, then add to it total numbers divided in 2
Obviously, I'm missing a step or two here, or there is a simple mathematical formula for this and hopefully someone could nudge me in a right direction.
This is what I have so far, it doesn't work properly if start number set to 1 or 3
function show()
{
console.clear();
for(let i = 0, count = end.value - start.value, half = Math.round(count/2); i <= count; i++)
{
let result = Math.round((+start.value + i) / 2);
if (i && i % 2)
result = result + half -1;
console.log(i, "result:", result);
}
}
//ignore below
for(let i = 0; i < 16; i++)
{
const o = document.createElement("option");
o.value = i;
o.label = i;
start.add(o);
end.add(o.cloneNode(true));
}
start.value = 0;
end.value = 7;
function change(el)
{
if (+start.value > +end.value)
{
if (el === start)
end.value = start.value;
else
start.value = end.value;
}
}
<select id="start" oninput="change(this)"></select> -
<select id="end" oninput="change(this)"></select>
<button onclick="show()">print</button>
P.S. Sorry, about the title, couldn't come up with anything better to summarize this.
You could get the value form the index
if odd by using the length and index shifted by one to rigth (like division by two and get the integer value), or
if even by the index divided by two.
function order(array) {
return array.map((_, i, a) => a[(i % 2 * a.length + i) >> 1]);
}
console.log(...order([3, 4, 5, 6, 7]));
console.log(...order([0, 1, 2, 3, 4, 5, 6, 7]));
So the basic premise is given 'n' amount of stairs, find all possible combinations of taking either 1 or 2 steps at a time. Since I spent a lot of time learning how to solve the Fibonacci sequence with recursion, I instantly noticed the similarity between the two problems. I figured out how to solve for the number of combinations... but I am utterly stuck when trying to figure out how to output each possible combination.
Here is the solution I have come up with...
function countWaysToReachNthStair(n) {
if (n === 1) { return 1; }
if (n === 2) { return 2; }
return countWaysToReachNthStair(n-1) + countWaysToReachNthStair(n-2)
}
console.log(countWaysToReachNthStair(4));
Every time I try to add things to an array to the output I either get an error. Any tips or tricks would be much appreciated...
The expected outcome for calling
countWaysToReachNthStair(4)
would be
5 ((1, 1, 1, 1), (1, 1, 2), (2, 1, 1), (2, 2))
Generators are a great fit for problems dealing with combinations and permutations -
function* ways(n) {
if (n <= 0) return
if (n <= 2) yield [n]
for (const w of ways(n - 2)) yield [2, ...w]
for (const w of ways(n - 1)) yield [1, ...w]
}
for (const w of ways(4))
console.log(`(${w.join(",")})`)
(2,2)
(2,1,1)
(1,2,1)
(1,1,2)
(1,1,1,1)
If you are interested in the total count, you can gather all ways into an array and read the length property of the result -
console.log(Array.from(ways(4)).length)
5
More or less as the OP understands it...
function waysToReachNthStair(n) {
if (n === 1) return [[1]]; // there's one way to take 1 stair
if (n === 2) return [[2], [1,1]]; // there are two ways to take 2 stairs
return [
// prepend 1 to each way we can take n-1 stairs, and
// prepend 2 each way we can take n-2 stairs
...waysToReachNthStair(n-1).map(way => [1, ...way]),
...waysToReachNthStair(n-2).map(way => [2, ...way])
]
}
console.log(waysToReachNthStair(4));
Explaining map(), it says: given an array like [x, y, z, ...] and a function f, return a new array like [f(x), f(y), f(z), ...].
You can calculate the total number of steps and route to steps as:
const result = [];
function countWaysToReachNthStairHelper(n, arr) {
if (n === 1) {
result.push(arr.join("") + "1");
return 1;
}
if (n === 2) {
const str = arr.join("");
result.push(str + "1" + "1");
result.push(str + "2");
return 2;
}
arr.push(1);
const first = countWaysToReachNthStairHelper(n - 1, arr);
arr.pop();
arr.push(2);
const second = countWaysToReachNthStairHelper(n - 2, arr);
arr.pop();
return first + second;
}
function countWaysToReachNthStair(n) {
return countWaysToReachNthStairHelper(n, []);
}
console.log(countWaysToReachNthStair(4));
console.log(result);
I have two solutions to the same challenge, this classic fibonacci challenge that everyone knows how to solve it (even your pets).
I kindly ask you NOT to suggest any other solutions.
I just want to compare these two solutions. Thousands different solutions can be found with searches.
Challenge:
/*
0 1 2 3 4 5 6 7 8 9
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
fib(3) returns 2
fib(9) returns 34
and so on...
*/
Both solutions below are working fine. My only question is:
Does solution B run slower than solution A? Because in B we have this line below:
fibArr.push(fibArr[fibArr.length - 1] + fibArr[fibArr.length - 2])
Does the length function go through the entire array to calculate the number of items? Or already returns from immediately?
Solution A:
function fib(n) {
const fiboArray = [0,1]
for(let i=2; i <= n; i++) {
fiboArray.push(fiboArray[i-2] + fiboArray[i-1])
}
return fiboArray[n]
}
console.log(fib(5))
Solution B:
function fib(n) {
const fibArr = [0, 1, 1]
if(n == 0) {
return 0
}
if(n == 1 || n == 2) {
return 1
}
if (n > 2) {
for (let i = 3; i <= n; i++) {
fibArr.push(fibArr[fibArr.length - 1] + fibArr[fibArr.length - 2])
}
}
return fibArr[fibArr.length - 1]
}
console.log(fib(9))
I concur with CertainPerformance, Solution A is better.
In many situations using .length would be just as fast because the browser will pre-compute it and go just as efficiently as if you make a local variable yourself however I think in your case Solution A is better because you use push on the array during the loop so length will be recalculated.
The answer to this post talks about it but he doesn't have push like you do.
#MisterJojo can you please show me a code example to simplify it?
function my_Fibonacci(n)
{
let a = 0
, b = 1
, r = [0, 1]
;
for(let i=2; i<=n; i++)
{
r.push(a+b) // new fibonacci value
a = b // set a for next addition
b = r[i] // set b for next addition
}
// return r.join(' - ')
return b
}
document.write(my_Fibonacci(9))
My Question
Given a positive integer num, return the sum of all odd Fibonacci numbers that are less than or equal to num.
The first two numbers in the Fibonacci sequence are 1 and 1. Every additional number in the sequence is the sum of the two previous numbers. The first six numbers of the Fibonacci sequence are 1, 1, 2, 3, 5 and 8.
For example, sumFibs(10) should return 10 because all odd Fibonacci numbers less than or equal to 10 are 1, 1, 3, and 5.
My Answer
function sumFibs(num, total = [1, 1]) {
const n = total[total.length - 1] + total[total.length - 2];
if(n > num){
return total;
}
if(n %2 ==0){
total.push(n);
}
return sumFibs(num, total);
}
sumFibs(4);
The Problem
It keeps saying maximum call stack exceeded. I am pretty sure it is because of the second if statement. Any idea how I can fix this?
I even tried this:
function sumFibs(num, total = [1, 1]) {
const n = total[total.length - 1] + total[total.length - 2];
if(n > num){
return total;
}
let x = Array.from(n);
let y = x.filter((item)=>{
return item % 2== 0
})
total.push(...y)
return sumFibs(num, total);
}
sumFibs(4);
I finally got there, so to explain:
I was not adding the even Fibonacci numbers to the array, as pointed out by Pointy. This was making the array incorrect.
This needed to move to the end. Once all of the Fibonacci calculations had been made. Then I could filter and reduce the break out clause of the recursive function:
function sumFibs(num, total = [1, 1]) {
const n = total[total.length - 1] + total[total.length - 2];
if(n > num){
let answer = total.filter((item)=>{
return item % 2 != 0;
}).reduce((totalII, filteredItems)=>{
return totalII + filteredItems
}, 0)
return answer
}
total.push(n)
return sumFibs(num, total);
}
console.log(sumFibs(4));
console.log(sumFibs(75204));
For contrast, here's an iterative, O(1) space, alternative:
function f(n){
if (n < 1)
return 0;
let result = 1;
let a = 1
let b = 1
while (b <= n){
if (b & 1)
result += b;
[a, b] = [b, a + b]
}
return result;
}
console.log(f(10));
console.log(f(4));
console.log(f(75204));
the sum of even Fibonacci numbers below 4 mill : i am trying to do it using JavaScript, but i am getting infinity as an answer
but if i use small number such as 10, i am getting console.log() output with the result, is it possible to do that in JavaScript??
var fib = [1, 2];
for(var i =fib.length; i<4000000; i++)
{
fib[i] = fib[i-2] + fib[i-1];
}
//console.log(fib);
var arr_sum = 0;
for(var i = 0; i < fib.length; i++){
if(fib[i] % 2 === 0){
arr_sum += fib[i] ;
}
}
console.log(arr_sum);
So this is the problem:
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
The correct answer is 4613732.
On the script below, the answer would be from variable "sum". I assigned it an initial value of 2 since that is the first even number on our sequence. I used 3 more variables to traverse through this sequence. The loop runs normal Fibonacci sequence and the if statement filters even numbers and adds it to the sum.
I think this is the simplest and most intuitive code implementation.
var sum = 2;
var x = 1, y = 2, fib;
while(x < 4000000) {
fib = x + y;
x = y;
y = fib;
if(fib%2===0) sum += fib;
}
console.log(sum);
Two things before I get to coding:
You need to sum the even fibonacci numbers which VALUE below 4 Million (#Alnitak)
There is an "even fibonacci series" which can be calculated in a different manner, see here.
Alright here we go:
let fib = [0, 2];
for(let i = 2; fib[i-1] < 4000000; i++) {
fib[i] = 4 * fib[i - 1] + fib[i - 2];
}
fib.pop()
let sum = fib.reduce((a, c) => a + c, 0);
console.log(sum);
Edit
Without the fib.pop() I just added, the last element of the array would be a number > 4000000. Now you should be able to get the right result.