Why does it only sums the last two numbers? - javascript

I am trying to make a program that sums every number given as parameter. To do so, I wrote the following code:
var x = 0;
var i = 2;
while (isNaN(+process.argv[i + 1]) == false){
x = +process.argv[i] + +process.argv[i + 1];
i++;
}
console.log(x);
The problem is that the code I wrote sums only the 2 last parameter.
I launch my code using node sumArgs.js 1 2 3
and it returns 5.
What is the problem with my code and why isn't it working as planned ?

What is happening every time you loop through, it is taking the current parameter, and the next, and setting x to equal the sum of those.
x needs to be added to, not set. You can do this either:
x += process.argv[i]
or
x = x + process.argv[i]
I'm also not sure why you are adding 2 arguments each loop, as this will cause the sum to be incorrect at the end (unless you increment i twice each loop).
I should note that map reducing it, as in another comment, wouldn't work as the first 2 arguments would not be parameters passed to the program, they would be "node" and "program.js".
var x = 0;
var i = 2;
while (isNaN(+process.argv[i]) == false){
x = x + process.argv[i];
i++;
}
console.log(x);
However, what you could do is use slice:
var sum = process.argv.slice(2).reduce(function(previousValue, currentValue) {
return previousValue + currentValue;
});

Related

Why isn't my for loop in Javascript changing the variable amount?

I made a Javascript code that should take two numbers in an array, arrange them from lowest to highest, and then return the sum of every number between and including them. So sumAll(1, 4) // returns the sum of 1 + 2 + 3 + 4 which is 10. However, when I do it, my variable total does not change from 0 with my for loop.
var sumAll = function(arr) {
var lower = Math.min(arr[0], arr[1]);
var upper = Math.max(arr[0], arr[1]);
var total = 0;
for (var i = lower; i <= upper; i++) {
total += i;
}
return total;
}
This code should return 10 when using 1 and 4, but it gives 0 because var total = 0. When I manually change var total to equal 10, then it turns to ten, which means my for loop is not working the way it should, and I have no idea why. Any help is greatly appreciated, I am super new to coding and have been working on this for a while.
Also, this is a TDD project so it is attached to a spec js file. So the only other part of this code is not actually me calling the array but
module.exports = sumAll
The spec file asks for this:
var sumAll = require('./sumAll')
describe('sumAll', function() {
it('sums numbers within the range', function() {
expect(sumAll(1, 4)).toEqual(10);
});
The code in your question works well, however, if you still have issues you could try this:
function sumAll(n1, n2) {
var numbers = [];
numbers.length = Math.abs(n2-n1)+1; numbers.fill(0);
numbers = numbers.map((i, j) => (Math.min(n1,n2)+j))
return numbers.reduce((acc, i) => (acc+=i))
}
sumAll(1,4); //10

Sum of Odd Fibonnaci failing with Higher values?

So im running into an odd error, where im summing all fibonnaci numbers that are odd and LESS than a number.
the odd thing is this works with low values, but when I get to upper values past 10 or so.....it'll crash codepen.io
here is what I have so far:
function f(n)
{
if(n <= 1)
return n;
return f(n-1)+f(n-2);
}
function sumFibs(num) {
var counter = 0;
var arr = [];
//Get all Fibbonaci Numbers up to num
for(let i = 1;i <= num;i++)
{
arr.push(f(i));
}
for(let j = 0;j < arr.length;j++)
{
if(arr[j] % 2 != 0 && arr[j] <=num)
{
counter+= arr[j];
}
}
console.log(counter);
return counter;
}
sumFibs(10);
Basically I calculate fib up to the num and then I go through each odd one thats less than or equal to num and add those up.
Im getting correct values (IE for 10 i get 10, for 4 i get 5....etc...)
but if I put in something like 1000 it seems to just crash? and I can't seem to figure out any reason why?
The recursive f() function is a logical way to express a Fibonacci number calculation, but it isn't very efficient compared to an iterative approach, especially because you are calling it repeatedly from inside a loop. I think this is bringing your browser to a halt. Within the loop each time you call f() it is calculating the specified Fibonacci number from scratch by recursively calling itself. So, say, to get f(10), it calls itself twice with f(9) + f(8) (and then they in turn call f(8)+f(7) and f(7)+f(6), etc., so even that is pretty inefficient), but in fact you already know what f(9) and f(8) are because you've stored those values in your array on previous loop iterations.
If you change your loop to calculate each subsequent number directly rather than calling another function you get much faster code:
var arr = [1, 1]; // start with the known first two numbers
//Get all Fibbonaci Numbers up to num
for(let i = 2; i < num; i++) // start the loop at index 2 for the third number
{
arr[i] = arr[i-2] + arr[i-1];
}
With that change in place, your sumFibs() function can give you results even for sumFibs(1000000) in a matter of milliseconds:
function sumFibs(num) {
var counter = 0;
var arr = [1, 1];
//Get all Fibbonaci Numbers up to num
for (let i = 2; i < num; i++) {
arr[i] = arr[i - 2] + arr[i - 1];
}
for (let j = 0; j < arr.length; j++) {
if (arr[j] % 2 != 0) {
counter += arr[j];
}
}
return counter;
}
console.log('10: ' + sumFibs(10));
console.log('100: ' + sumFibs(100));
console.log('1000: ' + sumFibs(1000));
console.log('10000: ' + sumFibs(10000));
console.time('High fib');
console.log('1000000: ' + sumFibs(1000000));
console.timeEnd('High fib');
Note that you also had a logic error in your second loop, the one that adds up the odd numbers: the && arr[j] <=num part needed to be removed. The values in arr are the actual Fibonacci numbers, but num is the sequence number, so it doesn't make sense to be comparing them. You just want every odd number in the whole array.
However, the return value from your function is still going to be incorrect if num is too large. That's because by the time you get to the 80-somethingth Fibonacci number it is larger than JavaScript can handle without losing precision, i.e., larger than Number.MAX_SAFE_INTEGER, 9,007,199,254,740,991 (which is 2^53 - 1). Numbers above that start getting rounded so your tests for odd numbers aren't reliable and thus the total sum doesn't include all of the numbers it should have, or if you add too many JS considers your result to be Infinity.

Applying Fibonacci, working with large numbers

I am trying to successfully complete this challenge on the Rosalind page. The challenge is:
Given: Positive integers n≤40 and k≤5.
Return: The total number of rabbit pairs that will be present after n months if we begin with 1 pair and in each generation, every pair of reproduction-age rabbits produces a litter of k rabbit pairs (instead of only 1 pair).
The exercise gives a text file of two numbers, the n and k mentioned above.
My code, which attempts to implement Fibonacci, works as expected for lower numbers of months. However, the result begins to become extremely large for higher numbers of months, and in each case I am given, my answer is Infinity.
Is my formula applied incorrectly? Or is Javascript a bad choice of language to use for such an exercise?
My code:
function fibonacciRabbits(months, pairs){
var months = months;
var numberOfPairs = pairs;
var result = 0;
// Declare parent & child arrays with constants
var parentArr = [1, numberOfPairs + 1]
var childArr = [numberOfPairs, numberOfPairs]
var total = []
// Loop from the point after constants set above
for(var i = 2; i < months - 2 ; i++){
parentArr.push(parentArr[i-1] + childArr[i-1])
childArr.push(parentArr[i-1] * childArr[i-2])
total.push(parentArr[i-1] + childArr[i-1])
}
result = childArr[childArr.length - 1] + parentArr[parentArr.length - 1]
console.log(months + ' months and ' + numberOfPairs + ' pairs:\n')
console.log('parentArr:\n', parentArr)
console.log('childArr:\n', childArr)
console.log('total\n', total)
console.log('result:', result)
console.log('\n\n\n')
}
fibonacciRabbits(5, 3)
fibonacciRabbits(11, 3)
fibonacciRabbits(21, 3)
fibonacciRabbits(31, 2)
And here is a REPL
Here is a more brief solution that doesn't produce such large numbers, and handles the maximum case without hitting infinity in Javascript. I think your solution was getting too big too fast.
function fibonacciRabbits(months, reproAmount){
var existingAdults = 0;
var adultPairs = 0;
var childPairs = 1;
for(var i = 2; i <= months; i++){
adultPairs = childPairs; //children mature
childPairs = (existingAdults * reproAmount); //last month's adults reproduce
existingAdults += adultPairs; //new adults added to the reproduction pool
}
console.log(existingAdults + childPairs);
}
To make sure you are on the right track, test your function with:
fibonacciRabbits(1, 1);
fibonacciRabbits(2, 1);
Which from the website says: f(1)=f(2)=1. So these should both produce "1" no matter what. Your code produces "3" for both of these.

Why does my factorial function always return one?

I am trying to write a piece of code to solve a Coderbyte challenge, to calculate a number's factorial. Every time I run it, the factorial generated is one. What am I doing wrong?
var num
var array1 = new Array();
function FirstFactorial(num) {
for (var i = num; i>0; i--){ // 8 , 7, 6 , 5
for (var y = 0; y<num ; y++){ // 0, 1, 2, 3, 4
array1[y]=i; // we have an array that looks like [8,7,6,5,4,3,2,1]
};
};
var sum = 1
for (var x = 0; x<array1.length; x++){ // now I want to run up that array, reading the #s
sum = sum * array1[x];
return sum;
};
return sum
};
A few issues.
1/ This is minor but, when you multiply two numbers, you get a product, not a sum.
2/ You returned the value from within the loop which would mean, even if you fixed the other problems, it would return prematurely without having multiplied all the numbers.
3/ Your nested loop does not fill your array the way you describe, you should check it after population. Think about your loops expressed as pseudo-code:
for i = num downto 1 inclusive:
for y = 0 to num-1 inclusive:
array1[y] = i
You can see that the inner loop is populating the entire array with the value of the current i. So the last iteration of the outer loop, where i is one, sets the entire array to ones.
4/ In any case, you don't need an array to store all the numbers from 1 to n, just use the numbers 1 to n directly. Something like (again, pseudo-code):
def fact(n):
prod = 1
for i = 2 to n inclusive:
prod = prod * i
return prod
This is a much easier way to calculate the factorial of a number.
function factorial(num)
{
if(num === 1)
{
return num;
}
return num * factorial(num - 1);
}
However to fix your code you need to fix the initial loop that loads the numbers into the array. as well as remove the return statement in the bottom loop. Like so.
function FirstFactorial(num) {
for (var i = num; i>0; i--) {
array1[num - i] = i;
};
var sum = 1
for (var x = 0; x < array1.length; x++){ // now I want to run up that array, reading the #s
sum = sum * array1[x];
};
return sum
};

Do a calculation x times depending on a value

Math.floor((1600 * Math.pow(1.4, 19))); // = 956208
Im doing a fansite for a game and im trying to make a calculation how how much mana you need to get + skill the formula above calculates from 19-20 skill
but i need to loop the calculation x amount of times so you can calculate from x (19 in the calculation above) to y need to raise x+1 each time until it reaches the final value y and add up the answeres from each loop like below
i have 2 text boxes that i take the values from
956208+1338692+1874168+2623836+3673371+5142719 = 15608994 so it would end up doing something like that thats from 19 to 25
If I am understanding the problem correctly (it's a bit unclear...) you want something like this.
var from = 19;
var to = 25;
var totalMana = 0;
for (var i = from; i <= to; i++) {
totalMana += Math.floor(1600 * Math.pow(1.4, i));
}
console.log(totalMana); // 22,808,801
You simply loop from your lower value, through to your upper value, evaluating your formula each time and adding it to a accumulation variable that persists through each iteration.
Also, just so you know, you are dipping your toe in calculus. You are getting the summation of a finite series. Math is fun, even if you dont know your doing it :)
Gonna throw this answer in for fun:
// generate an array with each value in the series, where callback evaluates
// the value at each step
Math.series = function(from, to, callback){
var out = [];
for (var i = from; i <= to; i++)
out.push(callback.call(null, i));
return out;
};
// add the things in an array.
Math.sum = function(arr){
var sum = 0;
for (var i = 0; i < arr.length; i++)
sum += +arr[i];
return sum;
};
With these utility functions, you can accomplish your task in a one-liner like so:
Math.sum(Math.series(19,25,function(i){return Math.floor(1600*Math.pow(1.4,i));}));

Categories

Resources