Un compteur de suivi de plusieurs valeurs dans un tableau

Cela semble un peu complexe, donc je ferai de mon mieux pour être aussi clair que possible. La fonction particulière que je recherche dynamiquement crée un argent dépensé | L'argent a gagné le tableau pour un jeu de jeu.

J'ai une sorte de loterie que l'utilisateur peut parier. Il y a 6 articles que l'utilisateur peut acheter, chacun ayant 6 prix:

Entrez la description de l'image ici

Ceux-ci peuvent être placés dans des objets ou des tableaux.

var prices = [5,10,28,50,56,280] .

var possibleWins = [40,80,250,400,500,2500]

J'essaie de créer un graphique qui calcule combien d'argent vous devriez dépenser pour chaque article particulier par jeu afin de vous garantir de gagner de l'argent – pour 300 jeux.

Voici donc un exemple de la façon dont le graphique devrait débuter:

Entrez la description de l'image ici

Investissement = gains maximum possible + total dépensé (ce qui est négatif)

La 2ème ligne suppose que le premier jeu soit déjà passé et perdu. Etc.

L'idée est de commencer par l'élément le plus petit, mais abandonner une fois qu'il ne peut plus vous rendre positif même si vous gagnez. C'est pourquoi, à la ligne 9, nous passons au rock . (Notre investissement est à 0 et si nous jouons encore une brindille, le plus on peut gagner est 40. Donc, même si nous avons gagné, nous aurions effectivement perdu 5 dans l'ensemble).

Il convient également de souligner que si vous gagnez sur 1 élément; Vous gagnez sur tous les objets pour ce jeu en particulier. Donc, vous obtenez tous les prix combinés.

Je travaille depuis quelques jours maintenant et certaines de ces questions connexes ont mes premières tentatives (mais je n'ai honnêtement aucune idée):

Comment trouver la combinaison la plus faible possible de clés dans un tableau

Le compteur qui génère la somme la plus basse à partir d'une combinaison d'index au-dessus de la valeur précédente

Ajouter une arrays de touches à elles-mêmes jusqu'à dépassement d'une limite?

EDIT: Au moins 1 article (s) doit être acheté à chaque jeu et les jeux ne peuvent pas être ignorés

Fondamentalement, cette proposition repose sur une fonction pour obtenir les éléments suivants

  getItems = function () { var price = 0, array = lottery.map(function (a) { return a.price; }); return function () { var items; do { items = combine(array, price); price++; } while (!items.length) return items; } }(), 

Qui commence à un prix égal à zéro et augmente la valeur d'un jusqu'à une combinaison d'éléments. Ensuite, le tableau des items est renvoyé. La fonction fonctionne comme générateur.

L'autre fonction importante est la combinaison d'éléments avec un prix donné et l'essai d'obtenir un tableau avec les éléments.

 function combine(array, sum) { function c(left, right, sum) { if (!sum) { result = right; return true; } return left.some(function (a, i, aa) { return a <= sum && c(aa.slice(i + (a > sum - a)), right.concat(a), sum - a); }); } var result = []; c(array.sort(function (a, b) { return b - a; }), [], sum); return result; } 

combine prend un tableau avec les prix et une somme recherchée à atteindre en combinant les prix donnés. Si réussi, un tableau avec les éléments est renvoyé, sinon un tableau vide.

La troisième partie consiste à utiliser les articles tant que l'investissement n'est pas négatif. Si cela se produit, un nouvel ensemble d'objets est récupéré.

 function combine(array, sum) { function c(left, right, sum) { if (!sum) { result = right; return true; } return left.some(function (a, i, aa) { return a <= sum && c(aa.slice(i + (a > sum - a)), right.concat(a), sum - a); }); } var result = []; c(array.sort(function (a, b) { return b - a; }), [], sum); return result; } var lottery = [{ name: 'twig', price: 5, win: 40 }, { name: 'rock', price: 10, win: 80 }, { name: 'shell', price: 28, win: 250 }, { name: 'chip', price: 50, win: 400 }, { name: 'gold', price: 56, win: 500 }, { name: 'diamond', price: 280, win: 2500 }], lotteryByPrice = lottery.reduce(function (r, a) { r[a.price] = a; return r; }, Object.create(null)), getItems = function () { var price = 0, array = lottery.map(function (a) { return a.price; }); return function () { var temp; do { temp = combine(array, price); price++; } while (!temp.length) return temp; } }(), createTableRow = function (element) { var table = document.createElement('table'), tr = document.createElement('tr'); ['Game', 'Items', 'Types', 'Spend Per Game', 'Total Spend', 'Max. Possible Winnigs', 'Investment'].forEach(function (a) { var th = document.createElement('th'); th.appendChild(document.createTextNode(a)); tr.appendChild(th); }); table.appendChild(tr); element.appendChild(table); return function (row) { var tr = document.createElement('tr'); ['game', 'items', 'types', 'spend', 'total', 'potential', 'investment'].forEach(function (k) { var td = document.createElement('td'); td.appendChild(document.createTextNode(row[k])); tr.appendChild(td); }); if (row.topBorder) { tr.style.borderTop = '2px solid #666'; } table.appendChild(tr); }; }(document.body), row = { game: null, items: null, types: null, spend: null, total: 0, potential: null, investment: null }, i, items = getItems(), add = function (a, b) { return a + b; }, winP = function (a) { return lotteryByPrice[a].win; }, nameP = function (a) { return lotteryByPrice[a].name; }; for (i = 1; i <= 70; i++) { row.topBorder = false; while (row.total - items.reduce(add) + items.map(winP).reduce(add) < 0) { items = getItems(); row.topBorder = true; } row.game = i; row.items = items.length; row.types = items.map(nameP).join(' + '); row.spend = -items.reduce(add); row.total += row.spend; row.potential = items.map(winP).reduce(add); row.investment = row.potential + row.total; createTableRow(row); } 
 table { border-collapse: collapse; font-family: Sans-Serif; } th { border: 1px solid #ccc; padding: 0 10px; } td { text-align: center; border: 1px solid #ccc; } 

Voici ma solution

 let items = [{ name: 'twig', price: 5, win: 40 }, { name: 'rock', price: 10, win: 80 }, { name: 'shell', price: 28, win: 250 }, { name: 'chip', price: 50, win: 400 }, { name: 'gold', price: 56, win: 500 }, { name: 'diamond', price: 280, win: 2500 }]; let moves = []; Move.prototype.numberItems = function() { let count = 0; for (let n = 0; n < 6; n++) { count += this.counts[n]; } return count; } Move.prototype.nameItems = function() { let name = ''; for (let n = 0; n < 6; n++) { for (let x = 0; x < this.counts[n]; x++) { if (name != '') { name += ' - '; } name += items[n].name; } } return name; } Move.prototype.getWin = function() { let win = 0; for (let n = 0; n < 6; n++) { win += this.counts[n] * items[n].win; } return win; } function Move(cost, counts) { this.cost = cost; this.counts = counts.slice(); } function run() { createMoves(100); moves.sort(function(a, b) { return (a.cost - b.cost); }); print(); } function createMoves(maxCost) { let counts = []; for (let n = 0; n < 6; n++) { counts.push(0); } counts[0] ++; while (true) { let cost = whatCost(counts); if (cost < maxCost) { moves.push(new Move(cost, counts)); counts[0] ++; continue; } if (!escalate(counts)) { break; } } } function whatCost(counts) { let cost = 0; for (let n = 0; n < 6; n++) { cost += counts[n] * items[n].price; } return cost; } function escalate(counts) { for (let n = 0; n < 5; n++) { if (counts[n] != 0) { counts[n] = 0; counts[n + 1] ++; return true; } } return false; } function print() { let domResult = document.getElementById('results'); let game = 1; let moveInx = 0; let spent = 0; for (let moveInx = 0; moveInx < moves.length; moveInx++) { let myMove = moves[moveInx]; let items = myMove.numberItems(); let win = myMove.getWin(); let cost = myMove.cost; for (let repeat = 1;; repeat++) { let investment = win - spent - cost; if (investment < 0) { break; } spent += cost; let row = document.createElement('tr'); if (repeat == 1) { row.className = 'first'; } let cell = document.createElement('td'); cell.innerHTML = game; row.appendChild(cell); cell = document.createElement('td'); cell.innerHTML = items; row.appendChild(cell); cell = document.createElement('td'); cell.innerHTML = myMove.nameItems(); row.appendChild(cell); cell = document.createElement('td'); cell.innerHTML = cost; row.appendChild(cell); cell = document.createElement('td'); cell.innerHTML = spent; row.appendChild(cell); cell = document.createElement('td'); cell.innerHTML = win; row.appendChild(cell); cell = document.createElement('td'); cell.innerHTML = win - spent; row.appendChild(cell); domResult.appendChild(row); game++; if (game > 300) { return; } } } } 
 table { border-collapse: collapse; } tr * { border: solid 1px black; } .first { border-top: solid 4px blue; } 
 <button onclick="run()">Run</button> <table> <thead> <tr> <th>Game</th> <th>Items</th> <th>Types</th> <th>Spent</th> <th>Total Spent</th> <th>Max win</th> <th>Profit</th> </tr> </thead> <tbody id="results"> </tbody> </table> 

Vous pouvez créer un objet dans lequel les noms de propriété définissent les valeurs de possibleWins . Définissez toutes les combinaisons possibles pour investir la limite à chaque tour. Les tableaux ne contiennent pas toutes les combinaisons possibles de nombres inférieurs à la limite pour ce cycle particulier. C'est-à-dire que les chiffres ne sont pas dispersés dans toutes les combinaisons possibles. Par exemple, au tour 40 , [10, 10, 10, 10, 0, 0, 0, 0] est inclus comme un tableau; Bien que le tableau puisse également être réarrangé à [10, 0, 10, 10, 0, 10, 0, 10] ou autre combinaison d'index totalisant moins de 40 .

Une addition des combinaisons possibles possibles inférieures à la limit pour ce tour est poussée vers le tableau correspondant à un tour spécifique à l'objet renvoyé.

Cette implémentation n'essaie pas de localiser les itinéraires de sélection de chaque tour, ce qui entraînerait un résultat positif. L'ensemble des tableaux peut être itéré en fonction de chaque indice correspondant dans chaque tableau, une combinaison d'index aléatoires ou toutes les combinaisons possibles d'index.

L'approche est un modèle de base à partir duquel des sélections éventuelles peuvent être faites. D'autres tableaux optionnels contenant des combinaisons de valeurs moins le nom de la propriété de l'objet, c'est-à-dire le cycle particulier, ou les valeurs dans les tableaux à partir des tableaux des propriétés de l'objet ayant une valeur de nom de propriété inférieure à la ronde actuelle, peuvent être ajoutés au tableau des tableaux; Pour trouver les combinaisons de sélections qui conduisent au résultat attendu.

 const [prices, possibleWins] = [ [5, 10, 28, 50, 56, 280], [40, 80, 250, 400, 500, 2500] ]; const counteropts = (prices, possibleWins) => { let rounds = {}; for (let price of prices) { let [chance, limit] = [[], possibleWins[prices.indexOf(price)]]; for (let buyin = price - price; buyin <= limit; buyin += price) { chance[chance.length] = buyin; } if (chance[chance.length - 1] !== limit) { chance = [...chance, limit] } for (let odd of Array.of(chance)) { let options = Array(); for (let choice of odd) { options[options.length] = [...odd.map( v => v !== choice && v + choice <= limit ? v + choice : 0 )]; if (options.length === prices.length -1) { for (let option of options[0]) { let keys = options[0].map((_, index) => index + 1) .filter(key => key * option <= limit); let opt = Array(keys.length).fill(option); options = [...options , opt.length < options[0].length ? [...opt, ...Array(options[0].length - opt.length).fill(0)] : opt ]; } rounds[limit] = [...options]; } } } } return rounds } let opts = counteropts(prices, possibleWins); console.log(opts);