Related
Given a JavaScript function that takes in an array of numbers as the first and the only argument.
The function then removes one element from the array, upon removal, the sum of elements at odd indices is equal to the sum of elements at even indices. The function should count all the possible unique ways in which we can remove one element at a time to achieve balance between odd sum and even sum.
Example var arr = [2, 6, 4, 2];
Then the output should be 2 because, there are two elements 6 and 2 at indices 1 and 3 respectively that makes the combinations table.
When we remove 6 from the array
[2, 4, 2] the sum at odd indexes = sum at even indexes = 4
if we remove 2
[2, 6, 4] the sum at odd indices = sum at even indices = 6
The code below works perfectly. There might be other solutions but I want to understand this one, because I feel there is a concept I have to learn here. Can someone explain the logic of this algorithm please?
const arr = [2, 6, 4, 2];
const check = (arr = []) => {
var oddTotal = 0;
var evenTotal = 0;
var result = 0;
const arraySum = []
for (var i = 0; i < arr.length; ++i) {
if (i % 2 === 0) {
evenTotal += arr[i];
arraySum[i] = evenTotal
}
else {
oddTotal += arr[i];
arraySum[i] = oddTotal
}
}
for (var i = 0; i < arr.length; ++i) {
if (i % 2 === 0) {
if (arraySum[i]*2 - arr[i] + oddTotal === (arraySum[i - 1] || 0)*2 + evenTotal) {
result = result +1
};
} else if (arraySum[i]*2 - arr[i] + evenTotal === (arraySum[i - 1] || 0)*2 + oddTotal) {
result = result +1
}
}
return result;
};
I am trying to generate sprial matrix in javascript.
question
Given an integer A, generate a square matrix filled with elements from 1 to A^2 in spiral order.
input : 3
[ [ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ] ]
when input is 4
[ [1, 2, 3, 4],
[12, 13, 14, 5],
[11, 16, 15, 6],
[10, 9, 8, 7] ]
my approach is to create 2d array with 0 value and after that they will fill values.
let generateMatrix = function(A) {
let arr = [], counter = 1;
for (let i = 0; i < A; i++) {
let items = []
for (let j = 0; j < A; j++) {
items.push(0)
}
arr.push(items)
}
var spiralMatrix = function(arr) {
if (arr.length > 1) {
for (let i = 0; i < arr[0].length; i++) {
arr[0][i] = counter++;
}
}
return arr
}
return spiralMatrix(arr)
}
console.log(generateMatrix(2))
You could take loops for each edges and loop until no more ranges are avaliable.
function spiral(length) {
var upper = 0,
lower = length - 1,
left = 0,
right = length - 1,
i = 0,
j = 0,
result = Array.from({ length }, _ => []),
value = 1;
while (true) {
if (upper++ > lower) break;
for (; j < right; j++) result[i][j] = value++;
if (right-- < left) break;
for (; i < lower; i++) result[i][j] = value++;
if (lower-- < upper) break;
for (; j > left; j--) result[i][j] = value++;
if (left++ > right) break;
for (; i > upper; i--) result[i][j] = value++;
}
result[i][j] = value++;
return result;
}
var target = document.getElementById('out'),
i = 10;
while (--i) target.innerHTML += spiral(i).map(a => a.map(v => v.toString().padStart(2)).join(' ')).join('\n') + '\n\n';
<pre id="out"></pre>
This bit of code should do what you are trying to.
// This is your Editor pane. Write your JavaScript hem and
// use the command line to execute commands
let generateMatrix = function(A) {
let arr = [],
counter = 1;
for (let i = 0; i < A; i++) {
let items = [];
for (let j = 0; j < A; j++) {
items.push(0);
}
arr.push(items);
}
var spiralMatrix = function(arr) {
let count = 1;
let k = 0; // starting row
let m = arr.length; // ending row
let l = 0; // starting column
let n = arr[0].length; //ending column
while (k < m && l < n) {
// top
for (var i = l; i < n; i++) {
arr[k][i] = count;
count++;
}
k++;
// right
for (var i = k; i < m; i++) {
arr[i][n - 1] = count;
count++;
}
n--;
// bottom
if (k < m) {
for (var i = n - 1; i >= l; i--) {
arr[m - 1][i] = count;
count++;
}
m--;
}
// left
if (l < n) {
for (var i = m - 1; i >= k; i--) {
arr[i][l] = count;
count++;
}
l++;
}
}
return arr;
};
return spiralMatrix(arr);
};
console.log(generateMatrix(4));
This is in some ways the reverse of an answer I gave to another question. We can recursively build this up by slicing out the first row and prepending it to the result of rotating the result of a recursive call on the remaining numbers:
const reverse = a =>
[...a] .reverse ();
const transpose = m =>
m [0] .map ((c, i) => m .map (r => r [i]))
const rotate = m =>
transpose (reverse (m))
const makeSpiral = (xs, rows) =>
xs .length < 2
? [[... xs]]
: [
xs .slice (0, xs .length / rows),
... rotate(makeSpiral (xs .slice (xs .length / rows), xs.length / rows))
]
const range = (lo, hi) =>
[...Array (hi - lo + 1)] .map ((_, i) => lo + i)
const generateMatrix = (n) =>
makeSpiral (range (1, n * n), n)
console .log (generateMatrix (4))
A sharp eye will note that rotate is different here from the older question. transpose (reverse (m)) returns a clockwise rotated version of the input matrix. reverse (transpose (m)) returns a counter-clockwise rotated one. Similarly, here we rotate the result of the recursive call before including it; whereas in the other question we recurse on the rotated version of the matrix. Since we're reversing that process, it should be reasonably clear why.
The main function is makeSpiral, which takes an array and the number of rows to spiral it into and returns the spiraled matrix. (If rows is not a factor of the length of the array, the behavior might be crazy.) generateMatrix is just a thin wrapper around that to handle your square case by generating the initial array (using range) and passing it to makeSpiral.
Note how makeSpiral works with rectangles other than squares:
makeSpiral ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 2) //=>
// [
// [ 1, 2, 3, 4, 5, 6],
// [12, 11, 10, 9, 8, 7]
// ]
makeSpiral ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 3) //=>
// [
// [ 1, 2, 3, 4],
// [10, 11, 12, 5],
// [ 9, 8, 7, 6]
// ]
makeSpiral ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 4) //=>
// [
// [ 1, 2, 3],
// [10, 11, 4],
// [ 9, 12, 5],
// [ 8, 7, 6]
// ]
makeSpiral ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 6) //=>
// [
// [ 1, 2],
// [12, 3],
// [11, 4],
// [10, 5],
// [ 9, 6],
// [ 8, 7]
// ]
The other functions -- range, reverse, transpose, and rotate -- are general purpose utility functions for working with arrays or matrices.
Here's one solution.
I keep the current "moving direction" in dx and dy, such that the next matrix element indices are given by x+dx and y+dy.
If the next item is already filled or is out of bounds, I change this direction clockwise. Otherwise, I fill it with the next value.
const size = 6;
const matrix = Array(size).fill().map(() => Array(size).fill(0));
let x = -1;
let y = 0;
let dx = 1;
let dy = 0;
function changeDirection() {
if (dx === 1) {
dx = 0;
dy = 1;
} else if (dy === 1) {
dy = 0;
dx = -1;
} else if (dx === -1) {
dx = 0;
dy = -1;
} else {
dx = 1;
dy = 0;
}
}
for (let i = 0; i < size * size; i++) {
const yNext = y + dy;
const xNext = x + dx;
const nextRow = matrix[yNext] || [];
const nextItemContent = nextRow[xNext];
if (nextItemContent === undefined || nextItemContent > 0) {
changeDirection();
i--;
continue;
}
y = yNext;
x = xNext;
matrix[y][x] = i + 1;
}
const result = document.getElementById('result');
matrix.forEach(row => {
row.forEach(value => {
result.innerHTML += value.toString().padStart(3);
});
result.innerHTML += '\n';
});
<pre id="result"></pre>
I'm calculating the index, each number should go in a linear array
console.clear();
Array.prototype.range = function(a, b, step) {
step = !step ? 1 : step;
b = b / step;
for(var i = a; i <= b; i++) {
this.push(i*step);
}
return this;
};
const spiral = function(dimen) {
"use strict";
const dim = dimen;
const dimw = dim;
const dimh = dim;
var steps = [1, dimh, -1, -dimh];
var stepIndex = 0;
var count = 1;
var countMax = dimw
var dec = 0
var index = 0;
var arr = [];
arr = arr.range(1, dimh * dimw)
const newArr = arr.reduce((coll, x, idx) => {
index += steps[stepIndex]
coll[index-1] = idx+1;
if (count === countMax) {count = 0; stepIndex++; dec++;}
if (dec === 1) {dec = -1; countMax--}
if (stepIndex == steps.length) {stepIndex = 0}
count++;
return coll;
}, []);
var ret = []
while (newArr.length) {
ret.push(newArr.splice(0,dimw))
}
return ret
}
console.log(spiral(3))
console.log(spiral(4))
console.log(spiral(5))
var n=14; // size of spiral
var s=[]; // empty instruction string
function emp() {} // no move
function xpp() {xp++;} // go right
function xpm() {xp--;} // go left
function ypp() {yp++;} // go down
function ypm() {yp--;} // go up
var r=[xpp,ypp,xpm,ypm]; // instruction set
s.push(emp); // push 'no move' (used for starting point)
var c=n-1;
while (c-->0) s.push(r[0]); // push first line - uses a different rule
for (var i=1;i<2*n-1;i++) { // push each leg
c=Math.floor((2*n-i)/2);
while (c-->0) s.push(r[i%4]);
}
var sp=new Array(n); // spiral array
for (var i=0;i<n;i++) sp[i]=new Array(n);
var xp=0; // starting position
var yp=0;
for (var i=0;i<n*n;i++) {
s[i](); // execute next instruction
sp[yp][xp]=i+1; // update array
}
for (var i=0;i<n;i++) console.log(sp[i].toString()); // log to console
This code makes a macro of functions to generate a run sequence, for example:
'right4, down4, left4, up3, right3, down2, left2, up1, right1
and then implements it.
Here is a solution to Spiral Matrix from leetcode, maybe this can help
https://leetcode.com/problems/spiral-matrix/
var spiralOrder = function(matrix) {
if (matrix.length == 0) {
return [];
}
let result = [];
let rowStart = 0;
let rowEnd = matrix.length - 1;
let colStart = 0;
let colEnd = matrix[0].length - 1;
while (true) {
// top
for (let i = colStart; i <= colEnd; i++) {
result.push(matrix[rowStart][i]);
}
rowStart++;
if (rowStart > rowEnd) {
return result;
}
// right
for (let i = rowStart; i <= rowEnd; i++) {
result.push(matrix[i][colEnd]);
}
colEnd--;
if (colEnd < colStart) {
return result;
}
// bottom
for (let i = colEnd; i >= colStart; i--) {
result.push(matrix[rowEnd][i]);
}
rowEnd--;
if (rowEnd < rowStart) {
return result;
}
// left
for (let i = rowEnd; i >= rowStart; i--) {
result.push(matrix[i][colStart]);
}
colStart++;
if (colStart > colEnd) {
return result;
}
}
return result;
};
console.log(
spiralOrder([[2, 3, 4], [5, 6, 7], [8, 9, 10], [11, 12, 13], [14, 15, 16]])
);
console.log(spiralOrder([[7], [9], [6]]));
console.log(spiralOrder([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]));
console.log(spiralOrder([[1, 2, 3], [4, 5, 6], [7, 8, 9]]));
Here's my answer using only one for loop -
function matrix(n) {
const arr = [];
let row = 0;
let column = 0;
let counter = 1;
let edge = n - 1;
let leftToRightRow = false;
let topToBottomCol = false;
let rightToLeftRow = false;
let bottomToTopCol = false;
for (i = 0; i < n * n; i++) {
if (column <= edge && !leftToRightRow) {
if (!Array.isArray(arr[row])) {
arr[row] = []; // if array is not present at this index, then insert one
}
arr[row][column] = counter;
if (column == edge) {
row = row + 1;
leftToRightRow = true;
} else {
column = column + 1;
}
counter = counter + 1;
} else if (column === edge && !topToBottomCol) {
if (!Array.isArray(arr[row])) {
arr[row] = []; // if array is not present at this index, then insert one
}
arr[row][column] = counter;
if (row === edge) {
column = column - 1;
topToBottomCol = true;
} else {
row = row + 1;
}
counter = counter + 1;
} else if (column >= 0 && !rightToLeftRow) {
arr[row][column] = counter;
if (column === 0) {
row = row - 1;
rightToLeftRow = true;
} else {
column = column - 1;
}
counter = counter + 1;
} else if (row >= n - edge && !bottomToTopCol) {
arr[row][column] = counter;
if (row === n - edge) {
column = column + 1;
bottomToTopCol = true;
//setting these to false for next set of iteration
leftToRightRow = false;
topToBottomCol = false;
rightToLeftRow = false;
edge = edge - 1;
} else {
row = row - 1;
}
counter = counter + 1;
}
}
return arr;
}
Solution is implemented in C++, but only logic matter then you can do it in any language:
vector<vector<int> > Solution::generateMatrix(int A) {
vector<vector<int>> result(A,vector<int>(A));
int xBeg=0,xEnd=A-1;
int yBeg=0,yEnd=A-1;
int cur=1;
while(true){
for(int i=yBeg;i<=yEnd;i++)
result[xBeg][i]=cur++;
if(++xBeg>xEnd) break;
for(int i=xBeg;i<=xEnd;i++)
result[i][yEnd]=cur++;
if(--yEnd<yBeg) break;
for(int i=yEnd;i>=yBeg;i--)
result[xEnd][i]=cur++;
if(--xEnd<xBeg) break;
for(int i=xEnd;i>=xBeg;i--)
result[i][yBeg]=cur++;
if(++yBeg>yEnd) break;
}
return result;
}
Solition in c#:
For solving this problem we use loops for each moving directions
public IList<int> SpiralOrder(int[][] matrix) {
var result = new List<int>();
var n = matrix[0].Length;
var m = matrix.Length;
var i = 0;
var j = 0;
var x = 0;
var y = 0;
while (true)
{
//left to right moving:
while (x <= n - 1 - i)
{
result.Add(matrix[y][x]);
x++;
}
if (result.Count == n * m)
return result;
x--;y++;
//up to down moving:
while (y <= m - 1 - j)
{
result.Add(matrix[y][x]);
y++;
}
if (result.Count == n * m)
return result;
y--;x--;
//right to left moving:
while (x >= j)
{
result.Add(matrix[y][x]);
x--;
}
if (result.Count == n * m)
return result;
x++;y--;
//down to up moving:
while (y > j)
{
result.Add(matrix[y][x]);
y--;
}
if (result.Count == n * m)
return result;
y++;x++;
i++;
j++;
}
}
I don't know what's wrong, my function miniMaxSum isn't summing 1+3+4+5. At the end, the result array turns into this [ 14, 12, 11, 10 ], when it should looks like this [ 14, 13, 12, 11, 10 ]
function miniMaxSum(arr) {
let results = [];
let actualValue = 0;
let skipIndex = 0;
for (let i = 0; i < arr.length; i++) {
//skip actual index
if (i == skipIndex) continue;
actualValue += arr[i];
//restart the loop
if (i == arr.length - 1) {
skipIndex++;
results.push(actualValue);
actualValue = 0;
i = 0;
}
}
console.log(results);
console.log(Math.min(...results), Math.max(...results));
}
console.log(miniMaxSum([1, 2, 3, 4, 5]));
You're over-complicating your algorithm by trying to check whether you should add the current number to the overall sum or not. Instead, all you need to do is run a loop over your array, to sum up all your elements in your array. This will give you the total sum of all your elements. Then, again, iterate through your array. For each element in your array subtract it from the sum you just calculated and push it into a new array. This will give you the sum if you were to not use the number in the ith position. You can then find the min/max of this using JavaScript's Math.min and Math.max functions.
Here is an example using .reduce() and .map() to calculate the final result:
const miniMaxSum = arr => {
const sum = arr.reduce((s, n) => n+s, 0)
const results = arr.map(n => sum - n);
return [Math.min(...results), Math.max(...results)];
}
const [min, max] = miniMaxSum([1, 2, 3, 4, 5]);
console.log(min, max);
If you prefer standard for loops, here is an implementation of the above in a more imperative style:
const miniMaxSum = arr => {
let sum = 0;
for(let i = 0; i < arr.length; i++) { // sum all elements
sum += arr[i];
}
let results = [];
for(let i = 0; i < arr.length; i++) {
results[i] = sum - arr[i]; // sum minus the current number
}
return [Math.min(...results), Math.max(...results)];
}
const [min, max] = miniMaxSum([1, 2, 3, 4, 5]);
console.log(min, max);
Assuming you're talking about this question.
Whenever you want to restart the loop, you're setting i=0 but observe that you also have increment statement i++ in for loop so, effectively i starts from 1, not 0. You need to set i=-1 so that i=-1+1 = 0 in subsequent iteration. After doing this, you need to handle a corner case. When skipIndex==arr.length-1, check if i == arr.length-1. If yes, do results.push(actualValue); for the last value and then for loop terminates because i < arr.length is false in next iteration.
Code:
function miniMaxSum(arr) {
let results = [];
let actualValue = 0;
let skipIndex = 0;
for (let i = 0; i < arr.length; i++) {
//skip actual index
if (i == skipIndex){
if(i == arr.length - 1)
results.push(actualValue);
continue;
}
actualValue += arr[i];
//restart the loop
if (i == arr.length - 1) {
skipIndex++;
results.push(actualValue);
actualValue = 0;
i = -1;
}
}
console.log(results);
console.log(Math.min(...results), Math.max(...results));
}
miniMaxSum([1, 2, 3, 4, 5]);
Output
[ 14, 13, 12, 11, 10 ]
10 14
Is this a good way or the best way to implement Counting Sort in Javascript?
Can't find a standard JS Counting Sort example.
function countingSort(arr){
var helper = []; // This helper will note how many times each number appeared in the arr
// Since JS arrary is an object and elements are not continuously stored, helper's Space Complexity minor that n
for(var i = 0; i<arr.length; i++){
if(!helper[arr[i]]){
helper[arr[i]] = 1;
}else{
helper[arr[i]] += 1;
}
}
var newArr = [];
for(i in helper){
while(helper[i]>0){
newArr.push(parseInt(i));
helper[i]--;
}
}
return newArr;
}
var arr = [5,4,3,2,1,0];
console.log(countingSort(arr)); // [0, 1, 2, 3, 4, 5]
The code is correct, with some comments:
In general, the use of for..in on arrays is discouraged, but unless you define enumerable properties on the Array prototype (which is a bad idea anyway), your use of it is fine to me
You could improve the part where you loop to push the same value several times. This can be done in "one" go by concatenating Array(helper[i]).fill(i) to the results.
You could also use reduce to make the function more functional programming style. In the extreme, it could look like this:
function countingSort(arr){
return arr.reduce( (acc, v) => (acc[v] = (acc[v] || 0) + 1, acc), [] )
.reduce( (acc, n, i) => acc.concat(Array(n).fill(i)), [] );
}
// Sample run:
var arr = [5,4,3,2,1,0];
console.log(countingSort(arr)); // [0, 1, 2, 3, 4, 5]
counting sort is to start by initializing an auxiliary array of length k, that will hold the count of each number. Each index has an initial value of 0. After that, you loop through the input array and increase the “count” for each value by 1 every time you encounter that number in the array. Now, the auxiliary array holds the number of times each element is in the input array. The last step is to loop from the minimum value to the maximum value. In this loop, you’ll loop through each corresponding value in the count array, and add the elements who’s count is greater than 0 to the array in sequential order. You add each item by using a secondary incrementing variable (e.g. if we’re using “i” to loop from the min to max values, then we’ll use “j” to loop through the array), then increasing that second incrementing variable so the next item is placed in the next highest array index, and finally you decrease the value of the current item in the count array so that you don’t add too many of elements that value.
const countingSort = (arr, min, max) => {
const count = {};
// First populate the count object
for (let i = min; i <= max; i++) {
count[i] = 0;
}
for (let i = 0; i < arr.length; i++) {
count[arr[i]] += 1;
}
/* Now, count is indexed by numbers, with values corresponding to occurrences, eg:
* {
* 3: 1,
* 4: 0,
* 5: 2,
* 6: 1,
* 7: 0,
* 8: 0,
* 9: 1
* }
*/
// Then, iterate over count's properties from min to max:
const sortedArr = [];
for (let i = min; i <= max; i++) {
while (count[i] > 0) {
sortedArr.push(i);
count[i]--;
}
}
return sortedArr;
};
console.log(countingSort([3, 6, 5, 5, 9], 3, 9));
const countingSort = (arr, min, max) => {
let counters = [...Array(max+1)].map(e => 0);
let result = []
for(let i = min; i < max; i++){
counters[arr[i]] += 1
}
for(let j = min; j <= max; j++){
while( counters[j] > 0){
result.push(j)
counters[j]--
}
}
return result
}
const countingSort = (arr, min, max) => {
const count = {};
// First populate the count object
for (let i = min; i <= max; i++) {
count[i] = 0;
}
for (let i = 0; i < arr.length; i++) {
count[arr[i]] += 1;
}
/* Now, count is indexed by numbers, with values corresponding to occurrences, eg:
* {
* 3: 1,
* 4: 0,
* 5: 2,
* 6: 1,
* 7: 0,
* 8: 0,
* 9: 1
* }
*/
// Then, iterate over count's properties from min to max:
const sortedArr = [];
for (let i = min; i <= max; i++) {
while (count[i] > 0) {
sortedArr.push(i);
count[i]--;
}
}
return sortedArr;
};
console.log(countingSort([3, 6, 5, 5, 9], 3, 9));
const countingSort = (arr, min, max) => {
const count = {};
// First populate the count object
for (let i = min; i <= max; i++) {
count[i] = 0;
}
for (let i = 0; i < arr.length; i++) {
count[arr[i]] += 1;
}
/* Now, count is indexed by numbers, with values corresponding to occurrences, eg:
* {
* 3: 1,
* 4: 0,
* 5: 2,
* 6: 1,
* 7: 0,
* 8: 0,
* 9: 1
* }
*/
// Then, iterate over count's properties from min to max:
const sortedArr = [];
for (let i = min; i <= max; i++) {
while (count[i] > 0) {
sortedArr.push(i);
count[i]--;
}
}
return sortedArr;
};
console.log(countingSort([3, 6, 5, 5, 9], 3, 9));
let a = [2, 1, 1, 0, 2, 5, 4, 0, 2, 8, 7, 7, 9, 2, 0, 1, 9];
let max = Math.max(...a);
let min = Math.min(...a);
function countingSort(arr) {
const count = [];
for (let i = min; i <= max; i++) {
count[i] = 0;
}
for (let i = 0; i < arr.length; i++) {
count[arr[i]]++;
}
const sortedArr = [];
for (let i = min; i <= max; i++) {
while (count[i] > 0) {
sortedArr.push(i);
count[i]--;
}
}
return sortedArr;
}
console.log(countingSort(a));
The simplest way to solve this problem you write like this:
const range = (start, stop, step) => {
if (typeof stop == "undefined") {
stop = start;
start = 0;
}
if (typeof step == "undefined") step = 1;
if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) return [];
let result = [];
for (let i = start; step > 0 ? i < stop : i > stop; i += step)
result.push(i);
return result;
};
const numbers = [1, 2, 2, 2, 1, 3, 3, 1, 2, 4, 5];
const max = Math.max.apply(Math, numbers);
let count = Array.apply(null, Array(max + 1)).map(() => 0);
for (x of numbers)
count[x] += 1;
let arr = [];
for (x in range(max + 1))
for (i in range(count[x]))
arr.push(parseInt([x]));
console.log(arr);
Change the given amount of money into minimum number of bills.
Inputs:
Amount: positive integer;
Bills: a sorted list of distinct positive integers (e.g. [1, 5, 10]).
Assumptions:
Amount does not exceed 100.
At most 4 bill values.
Must return 0 if the amount cannot be changed.
Examples:
Amount: 17, bills: [1, 5, 10], answer: 4 -> 10+5+1+1
Amount: 17, bills: [2, 4], answer: 0
Here's the code I have so far
function sort(array) {
for (var i = array.length - 1; i >= 0; i--) {
for (var j = 0; j < i; j++) {
if (array[j + 1] > array[j]) {
var z = array[j];
array[j] = array[j + 1];
array[j + 1] = z;
}
}
}
return array;
}
function change(amount, bills) {
sort(bills);
var result = [];
while (amount > 0) {
for (var i = 0; i < bills.length; i++) {
if (amount >= bills[i]) {
amount -= bills[i];
result.push(bills[i]);
i--;
}
}
}
return result.length;
}
console.log(change(17, [1, 5, 10])); // Expect: 4
console.log(change(17, [2, 4])); // Expect: 0
console.log(change(18, [2, 4])); // Expect: 5
//console.log(change(17, [3, 5])); // Expect: 5
There are 2 problems
One is that if the amount cannot be divided it doesn't return 0 but just lags out because it's an infinite loop.
Second is that in the last example, 17,[3,5] my code takes the 5 3 times and then realises that it can't do the remaining 2 and lags out, instead of doing 3 4 times and adding a 5.
Would really appreciate suggestions, or fixed code. Please keep it fairly simple I am just a starter.
If fixed your change function and added comments to explain my changes, let me know if you have any doubts
function change (amount, bills) {
//Asign sorted array of bills to possibleBills
var possibleBills = sort(bills);
var result = [];
//Asign amount to currentAmount
var currentAmount = amount;
//Sort through possibleBills
for (var i = 0; i < possibleBills.length; i++) {
//Perform action inside while loop if the current bill value can be substracted from currentAmount
while (currentAmount - possibleBills[i] >= 0) {
currentAmount -= possibleBills[i];
result.push(possibleBills[i]);
//End loop and return the length of result if currentAmount reaches 0
if (currentAmount === 0) {
return result.length;
}
}
}
//Return 0 if the amount couldn't be changed with the given bills
if (currentAmount > 0) {
return 0;
}
return result.length;
};
function change(amount, bills) {
const billsDesc = bills.sort((a, b) => b - a);
const give = {}
let remaining = amount;
for (const bill of billsDesc) {
const qty = Math.floor(remaining/bill);
give[bill] = qty;
remaining -= qty*bill;
}
give.totalQty = Object.values(give).reduce((curr, prev) => curr + prev, 0);
return remaining === 0? give.totalQty : 0;
}
console.log(`${change(17, [1, 5, 10])} should equal 4`);
console.log(`${change(17, [2, 4])} should equal 0`);
console.log(`${change(18, [2, 4])} should equal 5`);