J'essaye d'écrire un programme simple en JavaScript vanille pour l'haltérophilie. L'utilisateur entre une certaine quantité de poids et il renvoie les plaques de poids spécifiques à mettre de chaque côté de la barre.
Je prends ensuite ce nombre dans une fonction qui en soustrait 45 pour tenir compte du poids de la barre, puis divise ce nombre par 2 qui est le poids à mettre de chaque côté de la barre.
let plates = [44, 33, 22, 11, 5.5, 2.75];
J'ai un tableau avec chaque plaque de poids:
const num = document.getElementById("weightAmount").value;
function getWeightAmount (num) {
const newNum = num - 45;
const halfNum = newNum / 2;
return getWeights(halfNum);
}
J'ai du mal à boucler correctement le tableau pour obtenir ce que je veux. Si j'ai besoin, disons, de 60,5 livres de chaque côté, il devrait renvoyer 44, 11, 5,5. J'ai donc besoin de savoir quels nombres du tableau plaque correspondent au nombre renvoyé par ma première fonction.
J'ai un tableau vide appelé poids dans lequel je veux pousser les nombres du tableau plaques dans ce travail avec le poids qui est ensuite retourné.
Ma question est de savoir comment puis-je parcourir le tableau plaques pour déterminer quels poids sont nécessaires?
3 Réponses :
Voici une solution. Dans le cas où les plaques disponibles ne correspondent pas au poids cible, il renverra la combinaison de plaques disponibles qui s'additionnent le plus près de la cible. Adapté de cette réponse .
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]);
}
J'ai une solution simple ci-dessous si la valeur du poids cible sera toujours la somme des plaques disponibles. En supposant que le tableau de pondérations est trié dans un ordre décroissant. J'ai pensé à tous les poids disponibles et je ne passerai au poids suivant que si le total dépasse le poids total dont vous avez besoin.
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]
A parfaitement fonctionné! Merci!
Une solution possible à ce problème consiste à répéter indéfiniment jusqu'à ce que
À chaque étape d'itération, vous soustrayez le poids le plus élevé possible multiplié par le facteur le plus élevé possible, stockez les deux dans une structure de données appropriée (mon implémentation utilise simplement un Object ) et continuez. p>
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
Le problème est essentiellement une instance du problème Knapsack . p>
Notez que nous supposons que les plaques sont triées. Sinon, Array.find ne récupérera pas nécessairement le poids maximum qui peut être soustrait du poids total.
Trouvez le poids qui ne se divise qu'une fois en votre poids cible, ajoutez-le à la barre et soustrayez-le du poids cible. Répétez jusqu'à ce que le poids cible soit égal à zéro.
Vous parcourez un tableau avec
plates.forEach (function (plate) {}}pourfor (let plate of plates) {}Peut-être pertinent: Problème de sac à dos
Eh bien, comme mentionné par @ FK82, c'est Knapsack, mais légèrement modifié. Il s’agit en fait d’une version modifiée d’un problème de changement [