I have a rather simple javascipt formula:
Math.round(minMax[0] + ((minMax[1] - minMax[0]) / 2));
Value of minMax[0] is 1 and minMax[1] is 5
But for some reason i get the result 12 out of this. where i was expecting 3, now my guess is that it calculates ((minMax[1] - minMax[0]) / 2) to 2 but then adds them together as a string with the result of "1"+"2" = 12
What can i do to make javascript see this as numbers?
Update:
if i change the formula to the following then it workes, but is ugly as hell
index = Math.round(parseInt(minMax[0]) + ((parseInt(minMax[1]) - parseInt(minMax[0])) / 2));
Update 2: How min max is found, this is in Typescript
private getMinMaxIndex(parentIds: number[]): number[] {
var minIndex = 99999999;
var maxIndex = -1;
for (var k in parentIds) {
var index = this.getIndexOf(parentIds[k]);
if (index > maxIndex) maxIndex = index;
if (index < minIndex) minIndex = index;
}
return [minIndex, maxIndex];
}
...
var minMax = this.getMinMaxIndex(limitedParents);
index = Math.round(parseInt(minMax[0]) + ((parseInt(minMax[1]) - parseInt(minMax[0])) / 2));
Update 3:
private getIndexOf(id: number) {
var nodes: INode[] = this.nodes.Get();
for (var i in nodes) {
if (nodes[i].GetId() == id)
return i;
}
console.log("Unable to find parent index, for node id: " + id + " in swimlane " + this.Name + ", this should not happen and will break.");
console.log(nodes);
return null;
}
export interface INode{
GetId(): number;
...
}
export class SubmissionNode implements INode {
...
constructor(data: DiagramInputObject) {
this.data = data;
}
public GetId(): number {
return this.data.Id;
}
}
export interface DiagramInputObject {
Id: number;
...
}
Finally the DiagramInputObject in question that is how it is parsed into the code
{
Id: 1014,
UserId: 1,
Type: 0,
SwimLaneId: null,
SwimLaneName: null,
Submitted: new Date("3/9/2014 8:56:00 PM"),
ParentId: 9,
MergeId: null,
Exportable: false,
TypeData: "null",
}
private getIndexOf(id: number) {
var nodes: INode[] = this.nodes.Get();
for (var i in nodes) { // <---- PROBLEM HERE
if (nodes[i].GetId() == id)
return i;
}
console.log("Unable to find parent index, for node id: " + id + " in swimlane " + this.Name + ", this should not happen and will break.");
console.log(nodes);
return null;
}
Remember that in JavaScript, all (all!) array indexes are actually strings. A for in loop enumerates all of the keys of an object, and all keys of an object are strings. getIndexOf, then, returns a string.
You should just use a standard length-based for loop:
for(var i = 0; i < nodes.length; i++) {
/* same loop body */
}
As other people have pointed out, and i was already aware of, is that the variable is not a integer.
I was using typescript so i did not exepect this problem, to solve it have i added parseInt around the numbers to ensure it is an integer.
The wierd thing is that ((minMax[1] - minMax[0]) / 2) is calculated as a number, but where minMax[0] + ((minMax[1] - minMax[0]) / 2) is not. I can only guess that the /2 forces javascript to view the varaibles as integers, just wired that this dose not extend to minMax[0] +.
Related
I want create new number object with own properties from Number.
But when assign a number value to my variable, my variable turn to Number(primitive wrapper object).and loss own properties.How can I prevent this?
Example
class Fnumber extends Number {
value = 0;
[Symbol.toPrimitive](hint) {
if (hint === 'object') {
return this;
}
return this.value;
};
//I don't want use Number.prototype.add method because this effect all Number values.
add = function(...v) {
this.value += Array.prototype.slice.call(arguments).reduce((o, v) => o + v)
}
}
var nmbr = new Fnumber();
nmbr.add(4, 2, 4);
console.log(nmbr); //return a Object
console.log(nmbr + 4); //return 14 is number
nmbr = 14;
console.log(nmbr); //return not a Object its Primative number value
console.log(nmbr + 4); //return 14 a number
nmbr.add(4, 2, 4); //raise error.
When doing nmbr = 14 you assign 14 to nmbr, you are not changing the nmbr.value, you are overwriting the object. Instead call add and use nmbr.value when needed.
class Fnumber extends Number {
value = 0;
add(...v) {
this.value += Array.prototype.slice.call(arguments).reduce((o, v) => o + v)
}
}
var nmbr = new Fnumber();
nmbr.add(4, 2, 4);
console.log(nmbr.value);
nmbr.add(5);
console.log(nmbr.value);
nmbr.value = 25; // assign a value to nmbr.value
console.log(nmbr.value);
If you are not planning on reassigning the object, a good practice is to use const instead of var, see the error below.
class Fnumber extends Number {};
const nmbr = new Fnumber();
nmbr = 14;
I found the solution indirectly.
class Fnumber extends Number {
value = 0;
add(...v) {
this.value += Array.prototype.slice.call(arguments).reduce((o, v) => o + v)
}
}
//temğrary variable description
var _nmbr=new Fnumber();
//Define nmbr variable in global scobe
Object.defineProperty(window,"nmbr",{
enumerable: true,
configurable: true,
get() { return _nmbr; },
set(val) { if (typeof val=="number")_nmbr.value=val; }
});
nmbr=4;
console.log(nmbr+2);//output 6
//still nmbr variable is object,because assigned value to
_nmbr.value with above set method
nmbr.add(4, 2, 4);
console.log(nmbr+2);//output 16
I'm trying to identify if a value is a Perfect Square and if that's the case, I want to push it into an array. I know that there is a built-in function that allows for it but I want to create an algorithm that does it. :)
Input: num = 16
Output: [4]
Example 2:
Input: num = 25
Output: [5]
Example 2:
Input: num = 14
Output: []
var isPerfectSquare = function(value) {
var perfectSquareVal = []
var highestValue = value;
var lowestValue = 0;
while (lowestValue < highestValue) {
var midpoint = 1 + Math.floor((highestValue + lowestValue)/2);
if (midpoint * midpoint === value) {
perfectSquareVal.push(midpoint);
} else if (midpoint * midpoint > value) {
highestValue = midpoint;
} else if (midpoint * midpoint < value) {
lowestValue = midpoint;
}
}
console.log(perfectSquareVal);
};
isPerfectSquare(16);
That seems really complicated to check if a number is a square, you could simply check if the square root is an Integer:
var isPerfectSquare = function(value) {
return Number.isInteger(Math.sqrt(value));
}
And if the function returns true, then push to array.
You could change the algorithm a bit by
taking the arthmetic mean with a flored value,
return if the product is found (why an array for the result?),
check only the greater oroduct because the smaller one is included in the check for equalness,
use decremented/incremented values, becaus the actual value is wrong,
keep a pure function, take ouput to the outside.
var isPerfectSquare = function (value) {
var highestValue = value,
lowestValue = 0;
while (lowestValue < highestValue) {
let midpoint = Math.floor((highestValue + lowestValue) / 2),
product = midpoint * midpoint;
if (product === value) return midpoint;
if (product > value) highestValue = midpoint - 1;
else lowestValue = midpoint + 1;
}
};
console.log(isPerfectSquare(25));
console.log(isPerfectSquare(250));
I am trying to add multiple arrays in javascript.
Here are my arrays I have made, and are working.
function getAmountSpent(){
var amountSpent = ((Math.random() * 500) + 1);
return amountSpent.toFixed(2)
}
function getGift(){
var gift = ((Math.random()* 50) + 1);
return gift.toFixed(2)
}
var names = ["Jeremy","Arun","Alisa","Rohan","Dana"];
var spent = [];
for (let i = 0; i < 5; i++) {
spent.push(getAmountSpent());
}
var gifts = [];
for (let i = 0; i<5; i++) {
gifts.push(getGift());
}
What I need help with is adding these arrays in a new function. I have began writing the code, and I am not sure what is wrong.
var totals =[];
for (let i=0; i<5; i++) {
totals.push(getSumTotals())
}
function getSumTotals(a){
totals= spent+(spent * gifts);
return totals.toFixed(2)
}
From what you can see, I am trying to add up the totals much like this:
totals[0] = spent[0] + (spent[0] * gifts[0]);
totals[1] = spent[1] + (spent[1] * gifts[1]);
totals[2] = spent[2] + (spent[2] * gifts[2]);
totals[3] = spent[3] + (spent[3] * gifts[3]);
totals[4] = spent[4] + (spent[4] * gifts[4]);
if it helps, the professor added guided instructions for function getSumTotals(a) stating:
This function will return the sum of the elements in array a.
You will be passing the array that holds your totals to
the parameter a. Be sure to treat the values in a as numbers.
I am not sure if this helps but here is the output to my document.
Current Total should equal (spent) + (spent * gifts). For instance, for Jeremy in this example, current total should equal:
$36.55 + ($36.55*0.0626) = $38.83. Since there are many variables involved, I am not 100% sure what I should write for function getSumTotals(a)
The parameter "a" is a placeholder because I am not sure how many parameter values I need, and the proper format I need to use.
As for the code...
You're both
not passing an index to getSumTotals
not using this parameter within getSumTotals to access your spent and gifts arrays
var totals =[];
for (let i=0; i<5; i++) {
totals.push(getSumTotals(i)) // you were missing i
}
function getSumTotals(idx) { // I took liberties to rename this
totals = spent[idx] + (spent[idx] * gifts[idx]);
return totals.toFixed(2);
}
Now for the Math...
All that said, this math of spent[i] + spent[i] * gifts[i] doesn't make much sense either. Was this specified in the problem?
you may use like this
defined gifts
gifts=[45,43,32];
defined spends
spends=[43,32,21];
this is the getSumTotal funtion
getSumTotal=(x)=>(x.a+x.b)
this is where added
totals=gifts.map((d1,i)=>{
return fu({a:gifts[i],b:spends[i]})
})
I understand this is your assignment, however - if the idea is to both generate arrays, and then add them together, it is a redundant step. Just use the name array to iterate once and do all your calculations within that single loop.
Here, I had some fun and took some liberties, but hopefully you see why multiple arrays are redundant.
function getSumTotals() {
const getAmountSpent = () => Math.random() * 500 + 1;
const getGift = () => Math.random() * 50 + 1;
const names = ["Jeremy", "Arun", "Alisa", "Rohan", "Dana"];
let totals = []
names.forEach((name, i) => {
let spent = getAmountSpent()
let gifts = getGift()
let $$$ = (spent + spent * gifts).toFixed(2);
totals[i] = $$$
console.log(`${name} cost me $${$$$}${'!'.repeat(($$$/1000) | 1)}`)
});
return totals;
}
getSumTotals()
Note, that toString returns a type of "String", but not "Number".
When you try to sum a number with string, you get a concatenated string "1" + 2 = "12"
To turn a string into Number, you must use a Number("str") function, or just a bunary + before the string:
console.log( "1" + 2 );
console.log( Number("1") + 2 );
console.log( +"1" + 2 );
Also, you use the same loop 3 times, but can use just one loop instead, and call all functions inside the one loop. And use your array.length instead of fixed number 5:
let names = ["Jeremy", "Arun", "Alisa", "Rohan", "Dana"];
let spent = [];
let gifts = [];
let totals = [];
for (let i = 0; i < names.length; i++) {
spent.push( getAmountSpent() );
gifts.push( getGift() );
totals.push( getSumTotals(i) );
}
console.log( totals );
function getAmountSpent() {
return rand(1, 500, 2);
}
function getGift() {
return rand(1, 50, 2);
}
function getSumTotals(i) {
return +( spent[i] * ( 1 + gifts[i] ) ).toFixed(2);
}
function rand(from, to, fixed = 0){
return +(Math.random()*( to - from ) + from).toFixed(fixed);
}
P.s. Math.random() returns a number between 0 (included) and 1 (not included). If you need a random number between (example) 20 and 100, Math.random()*(100-20) will give a number between 0 and 80. After adding +20 to the result, you get a number from 20 to 100. That's what does this formula Math.random()*( to - from ) + from
P.P.s. Another way, to get the same thing:
var names = ["Jeremy", "Arun", "Alisa", "Rohan", "Dana"].reduce( (prev, elem) => {
let spent = rand(1, 500, 2);
let gift = rand(1, 50, 2);
prev[elem] = new UserData( spent, gift );
return prev;
}, {});
console.log( "Jeremy spent: " + names.Jeremy.spent );
console.log( names );
function rand(from, to, fixed = 0){
return +(Math.random()*( to - from ) + from).toFixed(fixed);
}
function UserData(spent, gift){
this.spent = spent;
this.gift = gift;
this.total = +(spent * ( 1 + gift )).toFixed(2);
}
/* Google → Array reduce, Constructor functions */
function getAmountSpent(){
let amountSpent = ((Math.random() * 500) + 1);
return Number(amountSpent.toFixed(2))
}
function getGift(){
let gift = ((Math.random()* 50) + 1);
return Number(gift.toFixed(2))
}
let names = ["Jeremy","Arun","Alisa","Rohan","Dana"];
let spent = [];
let gifts = [];
let totals =[];
for (let i = 0; i < names.length; i++) {
spent.push(getAmountSpent());
gifts.push(getGift());
totals[i] = (spent[i]+(spent[i] * gifts[i])).toFixed(2);
totals[i] = parseFloat(totals[i])
}
Hi there
I don't think you need a function to add the totals. you just need to loop through and assign totals[i] to spent[i] + (spent[i] * gifts[i]).
then you can use the parseFloat and toFixed function to change the string to a number. remember toFixed() function turns numbers to string. so you need to use the parseFloat to change it to number again as shown in the code above. or you can come up with an easy way of changing it to number. I hope this helps!
Dear all,
I am stuck with a problem I have to solve. I'm doing it in JavaScript, but this applied generally to any language and is more an algorithm issue than anything else.
Lets say I have an array with 5 values and the TOTAL of these values should always be 500 in the end. The start values are 100, 100, ... , 100.
Ok and now I want that for the case I change ONE value, the other values "adjust" in the way so the "total value" of 500 is kept. And they don't arrange in some random order, but keep they original position and "move" towards the balance so their original value is kept (a bit).
Example:
100 100 100 100 100
I set the first one to 0
Result should be:
0 125 125 125 125
Now I set the second to 0
Result should be:
31.25 0 156.25 156.25 156.25
I have a working prototype - but I am very unsatisfied with the results. And I believe it can be done a LOT easier, but I cant think of any.
Im attaching my JS source and its fully commented.
Here is the general idea:
INPUT:
- array: of N INT elemnt values
- changed: the index of the element that has been adjusted, this one will be ignored for the array adjustments
- arrayMin / arrayMax: the values that are considered limits for the array elements
- arraySum: defines the sum of the array - this is important to see to what SUM the array has to adjust
PROCESS:
- the array elements minus 1 (the one that is ignored) are counted
- the difference made by the one change of the whole sum is computed
- the difference that has to be made to one and each (except the changed) is computed
- now there is a loop which adds (or subtracts) the difference to each object
- if the object reaches its limits (min or max) nothing can be added or subtracted more and this element will be ingored for the rest computation
- what could not be added to these elements hitting the limit is saved in REST
- at the end the loop checks if there is any REST and if there is, the loops repeats with REST computed among elements that can and may be adjusted further
- NOTE: If the rest is really small - treat it
Should anyone be interested why and what for I need it - I was thinking of using four sliders that share one "total" value and you set them up according to your preferences and the others take values depending on the change.
Source:
JS source file
**Im open to ideas :) **
Thank you
Oliver
Without the min/max constraints the function could look like this:
function reMapArray(array, changed, arraySum) {
const sum = array.reduce( (a, b) => a+b );
const adjust = (sum - arraySum) / (array.length - 1);
return array.map( (a, i) => i === changed ? a : a - adjust );
}
// Demo use
let array = [100, 100, 100, 100, 100];
array[0] = 0;
array = reMapArray(array, 0, 500);
console.log(array.toString());
array[1] = 0;
array = reMapArray(array, 1, 500);
console.log(array.toString());
With the min/max verification added, it could look like this:
function reMapArray(array, index, minValue, maxValue, arraySum) {
const sum = array.reduce( (a, b) => a+b );
if (sum === arraySum) return array; // end recursion: solution found
const adjust = (arraySum - sum) / array.reduce(
// count the values that can still be modified
(c, a, i) => c + (i === index ? 0
: arraySum > sum ? a < maxValue
: a > minValue),
0);
// apply adjustment, but without getting out of range, and then recurse
return reMapArray(array.map( (a, i) =>
i === index ? a : Math.max(minValue, Math.min(maxValue, a + adjust)) ),
index, minValue, maxValue, arraySum);
}
// Demo use:
let array = [100, 100, 100, 100, 100];
array[0] = 0;
array = reMapArray(array, 0, 0, 150, 500);
console.log(array.toString());
array[1] = 0;
array = reMapArray(array, 1, 0, 150, 500);
console.log(array.toString());
Here the second output is different than with the first solution, because the maximum value has been set to 150, so an output with 156.25 is not allowed.
Java solution for those interested:
public class ArrayAutoAdjuster {
private double[] values = new double[5];
public ArrayAutoAdjuster(){
for(int i = 0; i < values.length; i++){
values[i] = 100;
}
}
public static void main(String args[]){
ArrayAutoAdjuster aaa = new ArrayAutoAdjuster();
aaa.setNewValue(0,0);
System.out.println(aaa.toString());
aaa.setNewValue(1, 0);
System.out.println(aaa.toString());
}
public void setNewValue(int position, double value){
if(values[position] == value){
return;
}
double diff = (values[position] - value)/(values.length-1);
for(int i = 0; i < values.length; i++){
values[i] = i == position ? value : values[i] + diff;
}
}
public String toString(){
String s = "";
for(int i = 0; i < values.length; i++){
s += values[i];
if(i < values.length-1){
s+=",";
}
}
return s;
}
}
Here's a solution with some logging and error checking.
var sum = function(acc, itemValue) { return acc + itemValue; };
var setInitialArray = function(numItems, total) {
console.log("Create array of " + numItems + " items that sum to " + total);
var itemValue = Math.floor(total / numItems);
var extra = total - (numItems * itemValue);
var initArray = Array.apply(null, Array(5)).map(Number.prototype.valueOf, itemValue);
initArray[0] += extra;
return initArray;
};
var adjustArray = function(itemIdx, newValue, items) {
if (!Number.isInteger(itemIdx) || itemIdx < 0 || itemIdx >= items.length) return items;
console.log("Set item " + (itemIdx + 1) + " to " + newValue);
var total = items.reduce(sum, 0),
origItemValue = items[itemIdx],
diffValue = origItemValue - newValue,
totalForRemainItems = total + diffValue,
numItems = items.length - 1;
if (diffValue === 0 || totalForRemainItems < 0) return items;
// make copy of items without the changing item
var newItems = [].concat(items);
newItems.splice(itemIdx, 1);
var itemValue = Math.floor(totalForRemainItems / numItems);
var extra = totalForRemainItems - (numItems * itemValue);
newItems.forEach(function(item, idx) { newItems[idx] = (idx === 0) ? itemValue + extra : itemValue; });
newItems.splice(itemIdx, 0, newValue);
return newItems;
};
var myArray = setInitialArray(5, 502);
console.log(myArray);
var myNewArray = adjustArray(2, 50, myArray);
console.log(myNewArray);
Here is the question that I need to consult for help:
Write a greedy algorithm to make change with the fewest coins possible
using the Greedy Algorithm. You are given an array of coin values and
an amount: computeChange(coins, amount). Return an array with the
counts of each coin.
For example: computeChange([50, 25, 10, 5, 1], 137) should return
the array [2, 1, 1, 0, 2] which indicates how many of each coin: 2
50-cent pieces, 1 quarter (25 cents), 1 dime (10 cents), no nickels (5
cents), and 2 pennies (1 cent), which add up to 137 cents.
The array you return from computeChange should be the same length as
the first argument (coins). Assume that coins contains the values of
different coin types in decreasing order.
The greedy algorithm says that you repeatedly look for the largest
coin less than or equal to the remaining amount of money, then
subtract that coin from the remaining amount. When the remaining
amount reaches zero (or less), return the counts of coins used. (This
algorithm is not always optimal.)
You can change the variables COINS, which gives the values of the
different coins you can use to make change, and AMOUNT, which is the
total value of the change to make. Changing these values might be
useful for debugging your program.
Here is my code which I did but it did not display the standard change for 36 cents. Can anyone help me? Thank you.
<html>
<head>
<title>The Greedy Algorithm</title>
<script>
// ======== Here is the problem to be solved: ========
COINS = [50, 25, 10, 5, 1];
AMOUNT = 137
coincount = [0,0,0,0,0];
// ======== Here is where your solution begins: ========
// define the function named computeChange here:
function computeChange(coins, amount) {
var i = 0; var creminder = AMOUNT; var ccoin;
while( i < COINS.length )
{
while ( COINS[i] <= creminder )
{
creminder = creminder - COINS[i];
ccoin = coincount [i] ;
ccoin += 1;
coincount [i] = ccoin ;
}
i++;
}
return coincount;
}
// ===================================================================
// ======== Everything below here simply displays your output ========
// ======== Do NOT change anything below this line ===================
// ===================================================================
function rightJustify(s, w) {
// return a string of width w with s in the rightmost characters and
// at least one space on the left. For simplicity, assume w < 20.
var slen = s.length;
var blanks = " "
return blanks.substr(0, Math.min(20, Math.max(1, w - slen))) + s;
}
function makeChange() {
// compute change as an array: each element of change tells
// how many of the corresponding value in COINS to give. The
// total value should equal AMOUNT.
var change = computeChange(COINS, AMOUNT);
// now format the results. Output should look like:
// NUMBER VALUE
// 1 50
// 0 25
// 1 10
// 1 5
// 3 1
// TOTAL AMOUNT: 68 (total is correct)
//
// First, we'll do some type checking in case change is not of the
// expected type.
change = [].concat(change); // force whatever it is to be an array
// it should be an array of numbers, so let's check
for (i = 0; i < change.length; i++) {
if (typeof(change[i]) != 'number') {
return "Error: the function computeChange did not return " +
"an array of numbers.";
}
}
if (change.length > COINS.length) {
return "Error: the function computeChange returned an array " +
"longer than the length (" + COINS.length + ") of COINS.";
}
if (change.length < COINS.length) {
return "Error: the function computeChange returned an array " +
"shorter than the length (" + COINS.length + ") of COINS.";
}
var output = "<pre>NUMBER VALUE\n"
var sum = 0;
for (i = 0; i < change.length; i++) {
sum += change[i] * COINS[i];
var n = change[i].toString();
var a = COINS[i].toString();
output += rightJustify(n, 4) + rightJustify(a, 9) + "\n";
}
output += "TOTAL AMOUNT: " + sum + " (total is ";
output += (sum == AMOUNT ? "correct" :
"incorrect, should be " + AMOUNT) + ")\n";
return output;
}
function runSolution()
{
parent.console.log('loaded, calling runSolution()\n');
parent.console.log('answer: ' + document.getElementById('answer').toString());
document.getElementById('answer').innerHTML = makeChange();
}
</script>
</head>
<body>
<!-- the output is displayed using HTML -->
<!-- the ? will be replaced with the answer -->
<div id = "answer">?</div></p>
<br>
<script>runSolution();</script>
</body>
</html>
Thoughts:
After reading the replys, first at thought is that this may be used to other codes that we didn't see here, so we need to make the function sufficient to solve the question by input, not using the GLOBAL VALUES like AMOUNT, COINS and coincount, instead, use params given like coins and amount, and return a self created coincount.
I'll explain this directly use comments in the codes
function computeChange(coins, amount) {
// Create a array that is used to return the final result, instead of the global one.
var coincount = [];
// use the given `amount` to set `creminder ` rather than `AMOUNT` which may not be accessible if your code is called otherplace rather than here.
var i = 0; var creminder = amount; var ccoin;
while( i < coins.length )
{
// Lazily init the used coin for coin type i to 0.
coincount[i] = 0;
while ( coins[i] <= creminder )
{
creminder = creminder - coins[i];
ccoin = coincount[i];
ccoin += 1;
coincount[i] = ccoin;
}
i++;
}
return coincount;
}
Your origin version's creminder is determined by AMOUNT, so no matter I call computeChanges(COINS, AMOUNT) or computeChanges(COINS, 37), the result will be the same, because the 37 in the second example is not used, ignored and creminder is still set to AMOUNT. Both Nina Scholz and I do is to make that given amount account, so it matters when your function generates a result set.
While the answers above are very correct, I think one could also think of the solution to this particular problem in a different way.
With the example of computeChange([50, 25, 10, 5, 1], 137), a single loop could be used to get the required solution.
function computeChange(changeArray, amount) {
const result = [];
for (let i = 0; i < changeArray.length; i++) {
let changeAmount = Math.floor(amount / changeArray[i]);
amount -= (changeArray[i] * changeAmount);
result.push(changeAmount);
}
return result;
}
computeChange([50, 25, 10, 5, 1], 137); // [2, 1, 1, 0, 2]
Some remarks:
You get values for coins and amount. The original function access
COINSand AMOUNT even if there is a local copy of this values.
creminder is not necessary, because you have amount.
ccoin is not necessary, because you can directly subtract the value of the selected coin from the amount.
var COINS = [50, 25, 10, 5, 1],
AMOUNT = 36; //137
function computeChange(coins, amount) {
var i = 0,
coincount = coins.map(function () { return 0; }); // returns an array and for each element of coins zero
while (i < coins.length) {
while (coins[i] <= amount) {
amount -= coins[i];
coincount[i]++;
}
i++;
}
return coincount;
}
out(JSON.stringify(computeChange(COINS, AMOUNT), null, 4), true);
function out(s, pre) {
var descriptionNode = document.createElement('div');
if (pre) {
var preNode = document.createElement('pre');
preNode.innerHTML = s + '<br>';
descriptionNode.appendChild(preNode);
} else {
descriptionNode.innerHTML = s + '<br>';
}
document.getElementById('out').appendChild(descriptionNode);
}
<div id="out"></div>
function cc(c, a) {
for (var ra=[],i=0,r=a; i<c.length; ra[i] = (r/c[i])|0, r -= ra[i]*c[i], i++);
return ra;
}
function cc2(c, a) {
return c.map((c, i) => { var t = (a/c)|0; a -= c*t; return t; })
}
cc([50, 25, 10, 5, 1], 137); // [2, 1, 1, 0, 2]
cc2([50, 25, 10, 5, 1], 137); // [2, 1, 1, 0, 2]