JS contactenate numbers from an array instead of adding them - javascript

I'm doing a JS course on Udemy and I'm stuck with a challenge and the course is really still quite basic so the code I'm writing is basic too.
const bills = [22, 295, 176, 440, 37, 105, 10, 1100, 86, 52];
let tips = [];
let totals = [];
const calcTip = function (bills) {
return bills >= 50 && bills <= 300 ? bills * 0.15 : bills * 0.2
}
// for (i = 0; i < bills.length; i++) {
// const newTips = [calcTip(bills[i])];
// tips.push(newTips);
// const newTotals = [(bills[i] + tips[i])];
// totals.push(newTotals);
// }
tips = [calcTip(bills[1])];
totals = [bills[1] + tips[1]];
console.log(bills, tips, totals);
At the minute the totals bit is only for the second item from bills as I wanted to know whether I do it okay, so I'd appreciate a tip why the totals results in NaN in my console. the bills and tips seem to be working fine.
Thank you!
the totals was meant to give me a sum of bill and tip

Related

why the last number of the exercise is NaN? [duplicate]

This question already has answers here:
What is an off-by-one error and how do I fix it?
(6 answers)
Closed last month.
im doing a exercise of bills, tips and total of the all.
const calcTip = function (bill) {
return bill >= 50 && bill <= 300 ? bill * 0.15 : bill * 0.2;
};
const billsArray = [22, 295, 176, 440, 37, 105, 10, 1100, 86, 52];
const tipsArray = [];
const totalsArray = [];
for (let i = 0; i <= billsArray.length; i++) {
const tip = calcTip(billsArray[i]);
tipsArray.push(tip);
totalsArray.push(tip + billsArray[i]);
}
console.log(billsArray, tipsArray, totalsArray);
It's all right but in the browser console said that last one is not a number? someone knows why? do i need to use float?
it's because you didn't set condition <= exactly in for loop. it should be i<billsArray.length
It's because of out of array index i <= billsArray.length
can fixable with i < billsArray.length or i <= billsArray.length - 1

Problem with the output of a for...loop - JavaScript

I'm working through a JavaScript challenge problem Find Numbers with the Same Amount of Divisors and have run into some trouble at the end of my code where a for loop is involved.
The problem:
Find all pairs of numbers between 1 and NMax that are diff numbers apart and share the same amount of divisors.
For example: For numbers between 1 and 50, there are 8 numbers share the same number of divisors: [[2,3], [14,15], [21,22], [26,27], [33, 34], [34, 35], [38, 39], [44, 45]]
In my code below, count_pairsInt(1,50) will return 8, but count_pairsInt (3,100) returns TypeError: Cannot read properties of undefined (reading '1').
I'm almost certain something has gone awry in the last for loop, but I can't quite get my mind around what it is. Could someone help me out?
function countPairsInt(diff, nMax) {
const numbers = [];
for (let i=1; i<=nMax; i++) {
numbers.push(i);
}
// divisors loops over each number passed in and returns the number of divisors for that number
function divisors(num) {
let divs = [];
for (let i=1; i<=num; i++) {
if (num % i === 0) divs.push(i);
}
return divs;
}
// create an array of arrays, each subarray contains the number and it's number of divisors by passing map over the numbers array.
const numsAndDivs = numbers.map(x=> [x, divisors(x).length]);
let equalDivs = 0;
for (let i=1; i<numsAndDivs.length-1; i++) {
if (numsAndDivs[i][1] === numsAndDivs[i+diff][1] ){
equalDivs++;
}
}
return equalDivs
}
countPairsInt(1, 50); // returns 8
countPairsInt(3, 100) // should return 7
You forgot to add a simple check that i + diff must be less than numsAndDivs.length. it was getting 100 in your case and there was no array of index 100 in numsAndDivs. hence the error.
if (i+ diff < numsAndDivs.length && numsAndDivs[i][1] === numsAndDivs[i+diff][1] ){
equalDivs++;
}

How to find all factors of a number for a given number range

How can I find all the existing factors between two number?
for example all the factors of 5 that are between 10 and 1000.
One thing I can think of is like this:
function getFactors(factor, numbers) {
let factors = new Array()
for (var i = numbers[0] ; i <= numbers[1] ; i++) {
if (i % factor == 0) factors.push(i)
}
return factors
}
console.log(getFactors(5, [50, 100]))
But the problem is that I have a big number range ([0, 10000]) and a small factor 0.01. so I think doing this using my solution will be too much in terms of performance (i need to do this check every tick).
so I was wondering what is the better way to do this?
You can achieve same thing without checking for every number between numbers[0] & numbers[1]. What you need basically is to get every multiple of factor between numbers[0] & numbers[1]. Below code does it:
function getFactors(factor, numbers) {
let factors = new Array();
let start = numbers[0]/factor;
let end = numbers[1]/factor;
for(var i=start; i<= end; i++) {
factors.push(factor*i);
}
return factors
}
console.log(getFactors(5,[50,100]))
//[50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]

How to loop through an array of numbers to see which numbers are relevant to another number?

I'm trying to write a simple program in vanilla JavaScript for weightlifting. The user inputs a certain amount of weight and it returns the specific weight plates to put on each side of the barbell.
I then take that number into a function which subtracts 45 from it to account for the barbell weight then divides that number by 2 which is the amount of weight to put on each side of the bar.
const num = document.getElementById("weightAmount").value;
function getWeightAmount (num) {
const newNum = num - 45;
const halfNum = newNum / 2;
return getWeights(halfNum);
}
I have an array with each weight plate:
let plates = [44, 33, 22, 11, 5.5, 2.75];
I'm having trouble correctly looping through the array to get what I want. If I need, say, 60.5 lbs on each side, it should return 44, 11, 5.5. So I need to figure out which numbers in the plate array fit in the number returned from my first function.
I have an empty array called weights which I want to push the numbers from the plates array into that work with the weight which then is returned.
My question is how do I loop through the plates array to figure out which weights are needed?
A possible solution to this is iterating indefinitely until either
you have a solution
the problem becomes unsolvable given the set of weights
Every iteration step, you subtract the highest possible weight times the highest possible factor, store both in a suitable data structure (my implementation simply uses an Object) and continue.
const plates = [44, 33, 22, 11, 5.5, 2.75];
// We assume that plates is always sorted
const determineWeights = (totalWeight) => {
let factor = 0;
let weights = {};
while (totalWeight > 0) {
weight = plates.find(weight => Math.floor(totalWeight / weight) > 0);
// There is no weight we can subtract from the total weight to solve the problem
// Hence, the problem is unsolvable and we return null to indicate that no solution exists
if (!weight) { return null; }
// Determine the factor with which to multiply the weight before we subtract from the total weight an subtract the product
factor = Math.floor(totalWeight / weight);
totalWeight = totalWeight - factor * weight;
// Store weight and factor
weights[weight] = factor;
}
return weights;
}
console.log(determineWeights(104.5)); // { "11": 1, "44": 2, "5.5": 1 }
console.log(determineWeights(60.5)); // { "11": 1, "44": 1, "5.5": 1 }
console.log(determineWeights(5.0)); // null
The problem is essentially an instance of the Knapsack problem.
Note that we assume that plates is sorted. Otherwise, Array.find will not necessarily retrieve the maximum weight that can be subtracted from the total weight.
I have a simple solution below if value of the target weight will always be the sum of the available plates. Assuming the weights array are sorted in a descending order. I loop thought all available weights and will only proceed to the next weight if the total exceeds the total weight you require.
function getWeights(targeWeight) {
let plates = [44, 33, 22, 11, 5.5, 2.75];
let totalWeight = 0;
let neededPlates = [];
let i = 0;
while(i < plates.length){
var pweight = totalWeight + plates[i];
if (pweight > targeWeight) {
i++;
continue;
}
totalWeight += plates[i];
neededPlates.push(plates[i]);
}
return neededPlates;
}
console.log(getWeights(60.5)); // [44, 11, 5.5]
console.log(getWeights(104.5)); //[44, 44, 11, 5.5]
Here's a solution. In the event that the available plates don't add up to the target weight, it will return the combination of available plates that add up closest to the target. Adapted from this answer.
function createSubsets(numbers, target) {
// filter out all items larger than target
numbers = numbers.filter(function (value) {
return value <= target;
});
// sort from largest to smallest
numbers.sort(function (a, b) {
return b - a;
});
var i;
var sum = 0;
var addedIndices = [];
// go from the largest to the smallest number and
// add as many of them as long as the sum isn't above target
for (i = 0; i < numbers.length; i++) {
if (sum + numbers[i] <= target) {
sum += numbers[i];
addedIndices.push(i);
}
}
return addedIndices.map(n => numbers[n]);
}

Coin Change Algorithm JS

I have been trying to come up with a solution for this algorithm for 3-4 days but nothing seems to work and the available solutions are a bit more advanced for me. It has to be solved with conditionals only so no recursion or dynamic programming.
I need to determine the least amount of coins necessary to give change given the following denominations: 1, 0.5, 0.2, 0.1, 0.05, 0.02 and 0.01.
Input is the following:
Price of an item
Sum paid by customer
Current ideas:
let price = +gets();
let paidSum = +gets();
//gets is used to accept number input
let change = paidSum - price;
I figured I could use Math.floor to isolate the integer part and subtract it but then I have no idea what to do with the remaining sum.
Would modulo work to test whether the remaining sum contains any of the remaining values for change and then subtract again until I reach zero?
I do realize this isn't the best formulated question but I am at a loss here and I've done every other task apart from this. Thanks.
Simpler, reverse and map the denominations in cents and return a new array with the number of coins you need for each denomination.
const coinsCents = [1, 2, 5, 10, 20, 50, 100]
const getChange = (amountInCents) => {
return coinsCents.reverse().map(coin => {
let amountCoin = Math.floor(amountInCents/coin)
amountInCents -= amountCoin * coin
return amountCoin
}).reverse()
}
With the denominations you have specified, the problem is simpler than the general change making problem. In this actual case we can be sure that using the largest denomination, that is not greater than the amount to pay, always leads to an optimal solution.
So then there is no need for recursion or dynamic programming. Just a simple loop will do.
I will here ignore the additional "layer" of getting the price of the bill and the amount that the customer pays. In the end the only thing that counts is the change amount to pay back to the customer. So this snippet asks for that change amount and returns the coins that need to be given as change.
function getChange(amount) {
amount *= 100; // Convert to number of cents
var denominations = [1, 2, 5, 10, 20, 50, 100]; // cents
var result = [];
while (amount > 0) {
var coin = denominations.pop(); // Get next greatest coin
var count = Math.floor(amount/coin); // See how many times I need that coin
amount -= count * coin; // Reduce the amount with that number of coins
if (count) result.push([coin/100, count]); // Store count & coin
}
return result;
}
// I/O management
change.oninput = function () {
var coins = getChange(this.value);
result.textContent = coins.map(([coin, count]) => `${count} x $${coin}`).join(" + ");
};
To be paid to customer: <input id="change">
<div>Coins to pay: <span id="result"></span></div>
var coins;
var coinArray = {};
var output = {};
/* Method to get coin value without decimal point - it is required because
* javascript will consider 5.6 as 6 if we do Math.round()
*/
function getRoundFigureCoinValue(x) {
return (x * 10 - ((x * 10) % 10)) / 10;
}
// Method to calculate possible combination of coins
function calculateCoins(input) {
let largestPossibleCoin = 1;
if (input) {
coins.forEach((x) => {
if (input >= x) {
largestPossibleCoin = x;
}
});
let remainingCents = input % largestPossibleCoin;
output[largestPossibleCoin] = getRoundFigureCoinValue(
(input / largestPossibleCoin).toFixed(1)
);
if (remainingCents && input > 1) {
calculateCoins(remainingCents);
}
return largestPossibleCoin;
}
}
// Method to be called to get output.
function calculatePossibleCoinCombinations(value) {
if (isNaN(value) || +value <= 0) {
console.log('Invalid input');
return;
} else {
console.log('Possible combinations are:')
value = +value;
}
coins = [1, 5, 10, 25];
while (coins.length) {
let largestPossibleCoin = calculateCoins(value) || 0;
let outputString = '';
coins = coins.filter((x) => x < largestPossibleCoin);
Object.keys(output).forEach((key) => {
outputString += `${output[key]} - ${key} cents; `;
})
console.log(outputString);
output = {};
}
}
/*
Sample inputs:
calculatePossibleCoinCombinations('89');
calculatePossibleCoinCombinations(10);
calculatePossibleCoinCombinations(0);
calculatePossibleCoinCombinations('someString');
calculatePossibleCoinCombinations(-10)
*/

Categories