Sum an array of numbers in Javascript using Recursion - javascript

Why isn't this working? I'm getting a stack too deep error:
var countRecursion = function(array) {
var sum = 0
var count = 0
sum += array[count]
count ++
if (count < array.length) {
countRecursion(array);
} else {
return sum
}
}

You made a mistake and reset sum and counter inside the recursive block. I simply moved them outside.
var countRecursion = function(array) {
sum += array[count]
count ++
if (count < array.length) {
countRecursion(array);
} else {
return sum
}
}
var sum = 0
var count = 0
countRecursion([1,2,3]);
alert(sum);
This code is not recursive but iterative. I am not 100% sure if that's what you really wanted. But since you mentioned it, some people down voted my answer since I only fixed your code, but didn't made it recursive I guess. For completeness, here is recursive version of your code:
var countRecursion = function(array, ind) {
if (ind < array.length) {
return array[ind] + countRecursion(array, ind + 1);
} else {
return 0;
}
}
var sum = 0
var count = 0
sum = sum + countRecursion([1,2,3, 5, 6, 7], count);
alert(sum);

For recursion: pass data up, return data down.
The original code has a different count variable, being a local variable defined in the function, that is initial set to 0. As such the base case is never reached and the function recurses until the exception is thrown.
In addition to using a variable from an outer scope (or another side-effect) this can also be addressed by by following the recommendation on how to handle recursion, eg.
var countRecursion = function(array, index) {
index = index || 0; // Default to 0 when not specified
if (index >= array.length) {
// Base case
return 0;
}
// Recurrence case - add the result to the sum of the current item.
// The recursive function is supplied the next index so it will eventually terminate.
return array[index] + countRecursion(array, index + 1);
}

I see what you're thinking.
The issue with your code is that everytime you call countRecursion, count goes back to 0 (since it's initialized to 0 within your function body). This is making countRecursion execute infinitely many times, as you're always coming back to count = 0 and checking the first term. You can solve this by either:
Initializing count outside the function body, that way when you do count++, it increases and doesn't get reset to 0.
Passing count along with array as a parameter. That way, the first time you call the function, you say countRecursion(array, 0) to initialize count for you.
Note that you have to do the same for sum, else that will also revert to zero always.
Finally, (and this doesn't have to do with the stack error) you have to actually call return countRecursion(array) to actually move up the stack (at least that's how it is in C++ and what not - pretty sure it applies to javascript too though).

Array sum using recursive method
var countRecursion = function(arr, current_index) {
if(arr.length === current_index) return 0;
current_index = current_index || 0;
return countRecursion(arr, current_index+1) + arr[current_index];
}
document.body.innerHTML = countRecursion([1,2,3,4,5, 6])

Related

Making a conditional function more efficient

I want to make a function that modifies a variable based on the given argument.
The function checks a variable and the number in that string. Then via the argument, I specify either increase or decrease the number by 1 (++1).
There is an array as well, that if the number is equal to the length of the array, then it turns to 1 and if the number is less than 1 then it is equal the size of the array. This is to make sure the number of the string does not get less than 1 or more than the length of the array.
the string with the number is Music1. So the circle would be like:
...., Music1, Music2, Music3, Music4, Music1, Music2, Music3, ....
var MyArray = ["Music1", "Music2", "Music3", "Music4"];
var currentMusic = "Music1";
$(".increase").on('click tap', nextMusic);
$(".decrease").on('click tap', previousMusic);
function nextMusic() {
unaryChange('plus')
}
function previousMusic() {
unaryChange('minus')
}
function unaryChange(operation) {
if (currentMusic === "Music4") {
currentMusic = "Music1"
} else if (currentMusic === "Music0") {
currentMusic = "Music4"
}
if (operation === "plus") {
currentMusic = currentMusic.replace(/\d+$/, function(n) {
return ++n
});
} else {
currentMusic = currentMusic.replace(/\d+$/, function(n) {
return --n
});
}
console.log(currentMusic);
$(".text").text(currentMusic);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="increase">increase</button>
<button class="decrease">decrease</button>
<p class="text">value</p>
The above method almost does the job, however I am looking for an easier and more professional solution. It does not look efficient. For example, there must be a better way to specify the argument operation instead of a string like plus, or the conditions.
I need this function to be rewritten in a better way, more professionally and works as described.
Thanks in advance.
It is better to work with array index instead of the values
function unaryChange(operation) {
var currentIndex = MyArray.findIndex(function(item) {
return item === currentMusic;
});
if(operation === 'plus') {
newIndex = currentIndex < MyArray.length - 1 && currentIndex + 1 || 0;
} else {
newIndex = currentIndex > 0 ? currentIndex -1 : MyArray.length -1;
}
currentMusic = MyArray[newIndex]
$(".text").text(currentMusic);
}
In this case whatever the size of the array it will work.
A working example https://jsbin.com/rahomorupa/4/edit?html,js,console,output
Building on Joe's answer I'd suggest you define constants for plus and minus as +1 and -1 respectively to simplify the increment/decrement logic, along with the modulus operator to handle the array wrap-around:
const PLUS = 1;
const MINUS = -1;
function unaryChange(operation) {
var currentIndex = MyArray.findIndex(function(item) {
return item === currentMusic;
});
// If it's invoked as unaryChange(PLUS) or unaryChange(MINUS)
// we don't need any conditional logic to handle the increment,
// and with the % operator we don't need additional bounds overflow
// logic. (This latter bit is complicated somewhat by the need to
// handle a minus step from index 0.)
const {length} = MyArray;
const newIndex = ((currentIndex + operation) % length + length) % length;
currentMusic = MyArray[newIndex]
$(".text").text(currentMusic);
}
The % operator returns the remainder of a division, which conveniently loops back around to 0 when used with an array index against the array length:
const array = ['first', 'second', 'third'];
for (let i = 0; i < 20; i++) {
console.log(array[i % array.length]);
}
You can pass a Boolean for plus, use an arrow function, and a ternary operator:
var MyArray = ["Music1", "Music2", "Music3", "Music4"];
var currentMusic = "Music1";
$(".increase").on('click tap', nextMusic);
$(".decrease").on('click tap', previousMusic);
function nextMusic() {
unaryChange(true)
}
function previousMusic() {
unaryChange(false)
}
function unaryChange(plus) {
currentMusic = currentMusic == "Music4" ? "Music1" : (currentMusic == "Music0" ? "Music4" : currentMusic);
currentMusic = currentMusic.replace(/\d+$/, n => plus ? ++n : --n);
console.log(currentMusic);
$(".text").text(currentMusic);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="increase">increase</button>
<button class="decrease">decrease</button>
<p class="text">value</p>
Since you have an array of music, it's better to use that instead. There's no need to operate from the text, you just need to update the array index to the next value and pass it to the function, and let it get the song name directly.
Since we want to be between the boundaries of 0 and the array length, here's what is used to do this:
Get the next song: (currentTrackIndex + 1) % tracks.length. That will get the next index value and apply modulo to it so it will round back if it exceedes the array length.
Get the previous song: (currentTrackIndex - 1 + tracks.length) % tracks.length. It's pretty much the same as getting the next song, save for the case when the index it's already at zero. If you apply modulo to a negative number, you will get a negative result and will mess up your array index. So instead of using a conditional clause ("if (currentTrackIndex === 0 ...)"), let's add the array length. Why? Because since 0 % n == 0 and n % n == 0, adding the array length will not change the modulo result, while keeping your index as a positive number.
(I changed the name from MyArray to tracks and unaryChange to changeTrack, to give it better meaning clarity)
var tracks = ["Music1", "Music2", "Music3", "Music4"];
var currentTrackIndex = 0;
$(".increase").on('click tap', nextMusic);
$(".decrease").on('click tap', previousMusic);
function nextMusic() {
//It will move to the next track. If it's over the array length, it will reset to 0
changeTrack((currentTrackIndex + 1) % tracks.length)
}
function previousMusic() {
//It will move to the previous song. If it's below zero, it will reset to the last track index
changeTrack((currentTrackIndex + tracks.length - 1) % tracks.length)
}
function changeTrack(newTrackIndex) {
currentTrackIndex = newTrackIndex;
var currentTrack = tracks[currentTrackIndex];
console.log(currentTrackIndex);
$(".text").text(currentTrack);
}
Here's how I'd do it. Since it seems that the word Music is just a prefix used to designate a particular unit, I wont store it over and over again in a array.
As for jQuery? Yeah, nah.
"use strict";
function byId(id){return document.getElementById(id)}
window.addEventListener('load', onLoaded, false);
function onLoaded(evt)
{
let prefix = 'Music';
let count = 4, index=0;
byId('increase').addEventListener('click', function(evt){index++; index %= count; update();}, false);
byId('decrease').addEventListener('click', function(evt){index--; if (index<0) index=count-1; update();}, false);
function update()
{
byId('status').textContent = `${prefix}${index+1}`;
}
}
<span id='status'>Music1</span><br>
<button id='increase'>+</button><button id='decrease'>-</button>
I think this is a good start. Accessing the indices of the array versus the values feels a lot cleaner. Using ternaries cleans up a lot of logic into one line as well.
var MyArray = ["Music1", "Music2", "Music3", "Music4"];
var currentMusic = 0;
$(".increase").on('click tap', unaryChange);
$(".decrease").on('click tap', unaryChange);
function unaryChange() {
if (event.target.className === "increase") {
currentMusic = (currentMusic < 3 ? currentMusic + 1 : 0)
} else {
currentMusic = (currentMusic > 0 ? currentMusic -= 1 : 3)
}
console.log(MyArray[currentMusic]);
$(".text").text(MyArray[currentMusic]);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="increase">increase</button>
<button class="decrease">decrease</button>
<p class="text">value</p>

Can't detect the cause of infinite loop in a 'while loop' in JS

I've got an infinite loop inside my while loop and I can't find the cause.
It's a simple function that returns the sum of the argument's digits. I use a while loop because it needs to add up the digits until it lands at a one digit number.
I made sure that I added a statement that would make sure that at a certain point the loop will break., But it obviously doesn't.
function digital_root(n) {
num = n;
sum = 0;
while (num.toString().length>1){
for (i=0; i<num.toString().length; i++) {
sum += parseInt(num.toString()[i])
}
num = sum;
}
return sum;
}
digital_root(456)
I get a warning that I have an infinity loop on line 4 (while loop).
I hoped that num=sumwould reassign the new integer (with reduced number of digits) to the numvariable and thus at some point break out of the loop. Is this wrong?
What further confuses me is that most of the JS editors I've used to debug the problem return an output, but it takes ages. So is it an infinite loop or is it not?
You have a nested loop structure where the first condition is always true.
For getting only a number below 10, you could call the function again as recursion.
function digital_root(n) {
var num = n.toString(), // declare and use the string value
sum = 0,
i;
for (i = 0; i < num.length; i++) {
sum += parseInt(num[i], 10)
}
return sum > 9
? digital_root(sum)
: sum;
}
console.log(digital_root(456));
After re-reading the question I noticed that you're trying to reduce an integer down to a single number. The issue with your code was that sum was set to 0, only before the while loop. Meaning that it didn't reset for the second, third, ... run.
Moving sum = 0 into the while loop resolves this issue. I've also added variable declarations at the top to avoid setting global variables.
function digital_root(n) {
var num, sum, i;
num = n;
while (num.toString().length > 1) {
sum = 0;
for (i = 0; i < num.toString().length; i++) {
sum += parseInt(num.toString()[i]);
}
num = sum;
}
return sum;
}
console.log(digital_root(456));
Here written in a recursive manner, a style that I personally more prefer:
function digital_root(integer) {
// guard against things that might result in an infinit loop, like floats
if (!Number.isInteger(integer) || integer < 0) return;
const chars = integer.toString().split("");
if (chars.length == 1) return integer;
return digital_root(
chars.map(char => parseInt(char))
.reduce((sum, digit) => sum + digit)
);
}
console.log(digital_root(456));
Since you already got the answer, here is another way to meet the result
function digital_root(n) {
// convert the number to string
// use split to create an array of number viz ['4','5','6']
// use reduce to sum the number after converting to number
// 0 is the initial value
return n.toString().split('').reduce((a, c) => a + parseInt(c, 10), 0)
}
console.log(digital_root(456))
Avoiding all the nested loops that lead to a situation such as that you're facing, I'd rather do it in a more readable way.
function digital_root(n) {
sum = n;
while(sum.toString().length > 1) {
sum = sum.toString()
.split('')
.map(digit => parseInt(digit, 10))
.reduce((acc, cur) => acc + cur);
}
return sum;
}
console.log(digital_root(456));

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.

How to add up numbers in a nested array javascript

Just working on a project and tried a few different solutions but with no results. Could someone help me with how to add up numbers in a nested array? Would I use reduce? or a for loop?
function balance(arr) {
if(typeof item == 'number') {
return arr;enter code here
} else {
return arr + balance(item);
}
}
Is this maybe what you are hoping for?
function balance(arr) {
return arr.reduce(function(sum, item) {
if(typeof item == 'number') {
return sum;
} else {
return sum + balance(item);
}
},0);
}
console.log(balance([1,2,[3,4],5]));
Just for the record (to disprove the assertion that recursion is required), here's a version that uses a sequential algorithm. Recursion is concise and (usually) easier to read, however if speed matters, it can be slow. However, based on results from jsPerf, script engines seem very much better at optimising recursive code than they used to be, at least for simple programs like this.
For comparison, I've included a recursive version using a plain loop, the jsPerf tests also include a (fixed) recursive version using reduce. I suspect Any's answer will be slowest as it calls slice and itself on every loop, but I didn't have time to fix it.
So I guess recursion is fine here as it is fast and concise.
/* Sum the values of nested arrays. Only checks if values are arrays,
** otherwise assumes they're numbers
**
** #param {Array} arr - array of numbers to process, may have
** nested arrays of numbers
** #returns {number} - sum of values or NaN if arr is not an Array
*/
function balance(arr) {
// Only process arrays
var isArray = Array.isArray;
if (!isArray(arr)) return NaN;
// Setup
var arrays = [], indexes = [];
var currentArray = arr;
var currentValue;
var sum = 0;
var i = 0, iLen = arr.length;
// Use <= length as must handle end of array inside loop
while (i <= iLen || arrays.length) {
currentValue = currentArray[i];
// If at end of current array, reset value to before entering array
// Reset i to previous value as will increment at the bottom
if (i == currentArray.length && arrays.length) {
currentArray = arrays.pop();
i = indexes.pop();
iLen = currentArray.length;
// If current value is an array, use it and reset loop control values
// set i to -1 as will increment at the bottom
} else if (isArray(currentValue)) {
arrays.push(currentArray);
indexes.push(i);
currentArray = currentValue;
i = -1;
iLen = currentArray.length;
// Otherwise, add the current value
// Will be undefined if at end of array so add zero
} else {
sum += +currentValue || 0;
}
// Increment i
i++;
}
return sum;
}
document.write(
'balance sequential 1: ' +
balance([1,[2,1,[1,2,-1],[1]],1,[2,1]]) // 11
+ '<br>balance sequential 2: ' +
balance([1,2,[3,4],5]) // 15
);
/* Sum the values of nested arrays. Only checks if values are arrays,
** otherwise assumes they're numbers
**
** #param {Array} arr - array of numbers to process, may have
** nested arrays of numbers
** #returns {number} - sum of values or NaN if arr is not an Array
*/
function balanceLoop(arr) {
if (!Array.isArray(arr)) return NaN;
for (var value, total=0, i=0, iLen=arr.length; i<iLen; i++) {
value = arr[i];
total += Array.isArray(value)? balanceLoop(value) : value;
}
return total;
}
document.write(
'<br>balanceLoop 1: ' +
balanceLoop([1,[2,1,[1,2,-1],[1]],1,[2,1]]) // 11
+ '<br>balanceLoop 2: ' +
balanceLoop([1,2,[3,4],5]) // 15
);
A simple recursive function:
function balance(arr, total) {
total = total || 0;
if (arr.length === 0) return total;
var head = arr[0];
if (typeof head === 'number') {
return balance(arr.slice(1), total += head);
} else {
return balance(head, total);
}
}
balance([1, [2, 1, 3, [43, 2]]])); // 52
DEMO
I would probably solve this using a recursive reduce, in the following manner:
function balance(arr) {
return arr.reduce(function(sum,item) {
return sum + (item instanceof Array ? balance(item) : item);
}, 0);
};
balance([1,[2,1,[1,2,-1],[1]],1,[2,1]]); // 11
If you don't mind the overhead, you could of course do this:
Number.prototype.balance = function() { return this; };
Array.prototype.balance = function() { return this.reduce(function(a,b) { return a + b.balance(); }, 0); }
[1,[2,1,[1,2,-1],[1]],1,[2,1]].balance(); // 11

recursive function breaking in if statement javascript

i'm in the process of trying to write a function that converts an amount into a specified number of coins. For this I'm calling a function on itself (I think this is recursive programming?). I'm having 2 problems.
When i call the function on itself in the else section of the if statement I get the error message. "Maximum call stack size exceeded" ? Not sure why this is as the call above is the same and works fine when this second call is commented out.
Also when the second call is commented out and the function runs the variable total should be increasing by 1 with each call. However it doesn't make it past 1. I thought this may be because the variable was being reset at the top to 0 with each call. However the remainder variable is also set to 0 decreases its value each time.
Can anyone explain what is happening here ? How is this problem best solved ?
Thanks
function amountCoins(amt, coins) {
var remainder = 0;
total = 0;
if(amt >= coins[0]) {
total += 1;
remainder = (amt - coins[0]);
return amountCoins(remainder, coins);
} else {
coins.shift();
//return amountCoins(remainder,coins);
}
alert(total);
}
amountCoins(121,[20,15,6,1]);
You can use .reduce() for this as an alternative.
And we don't really need loops where simple math can handle it.
var total = [20,15,6,1].reduce(function(obj, denomination) {
return {
total: obj.total + Math.floor(obj.amount / denomination),
amount: obj.amount % denomination
};
}, {amount:121, total:0}).total;
Or iterate the array.
var arr = [20,15,6,1], amount = 121, total = 0;
for (var i = 0; i < arr.length; ++i) {
total += Math.floor(amount / arr[i]);
amount %= arr[i];
}
I'd use a regular for loop instead, if I was you:
var amt = 121;
var coins = [20, 15, 6, 1];
var coinsUsed = {};
var totalCoins = 0;
for (var i = 0; i < coins.length; i++) {
if (coins[i] <= amt) {
coinsUsed[coins[i]] = Math.floor(amt / coins[i]);
amt -= coinsUsed[coins[i]] * coins[i];
totalCoins += coinsUsed[coins[i]];
} else {
coinsUsed[coins[i]] = 0;
}
}
console.log(coinsUsed, totalCoins);
Output:
Object {
1: 1,
6: 0,
15: 0,
20: 6
}
7
The problem is that your algorithm never ends. Every recursive function must have an end, if not it will produce a stack overflow (xD), because recursive calls are stored in a stack.
This would be a solution:
function amountCoins(amt, coins, total) {
var remainder = 0;
total = total || 0; //Default value 0 (for the first call)
if(coins.length == 0) return total; //This is the ending condition (no coins)
if(amt >= coins[0]) {
total += 1;
remainder = (amt - coins[0]);
return amountCoins(remainder, coins, total);
} else {
coins.shift();
return amountCoins(remainder, coins, total);
}
}
var coins = amountCoins(121,[20,15,6,1]); //Returns: 6
alert(coins);
As you can see, I turned total into a param so we can store it from call to call.
Hope this helps. Cheers
i think this is what you are trying to do:
function amountCoins(amt, coins) {
var remainder = 0;
if(coins.length == 0) {
return 0;
} else if(amt >= coins[0]) {
remainder = (amt - coins[0]);
return amountCoins(remainder, coins)+1;
} else {
coins.shift();
return amountCoins(remainder,coins);
}
}
var total = amountCoins(121,[20,15,6,1]);
alert(total)
There are a few things here
A recursive algorithm needs a terminating condition. ie. when the function is calling itself recursively it should stop the chain at some point. If it doesnt, the program will run out of memory to accomodate all the calls in the chain. Because this is a potentially dangerous condition, programming languages like javascript limit the depth of a recursive call. This is what is meant by the Maximum call stack size exceeded error.
In your program, logically, the terminating condition is when we run out of coins. so a
coins.length == 0 check that returns a 0 total (which in turn seeds the upward chain) will fix the problem
Usually in recursive algorithms the result is passed backwards, up the call chain and not stored in an external variable. So the incrementing total value is expressed with a return statement like return amountCoins(remainder, coins)+1;
Finally, this problem can be much easily implemented with for loops. Try to think by unwinding the recursive call chains and you'll figure out a loop solution.
You must return total not only if no coins left, but also if the last coin's value is bigger then the remaining value:
function amountCoins(amt, coins, total) {
total = total || 0;
if (coins.length == 0 || (amt < coins[0] && coins.length == 1)) return total;
if (amt >= coins[0]) {
total += 1;
remainder = (amt - coins[0]);
return amountCoins(amt - coins[0], coins, total);
} else {
coins.shift();
return amountCoins(remainder, coins, total);
}
}
This correction to your original code will work:
function amountCoins(amt, coins, total) {
total = total || 0;
if (amt === 0) return total;
// throw out all the coins that are too big
while (amt < coins[0]) coins.shift();
// use the largest coin possible, then recurse
total += 1;
remainder = amt - coins[0];
return amountCoins(remainder, coins, total);
}
alert(amountCoins(121,[20,15,6,1])); // alerts 7
It has the advantage of avoiding unnecessary if ... else statements, and the logic is bit clearer imo

Categories

Resources