简体   繁体   English

计数器跟踪数组内的多个值

[英]A counter keeping track of multiple values inside an array

This seems sort of complex so I'll do my best to be as clear as possible.The particular function I'm looking for dynamically creates a money spent | 这似乎有点复杂,所以我会尽我所能尽可能清楚。我正在寻找的特定功能动态创造了一笔钱。 money won chart for a game of gambling. 钱赢了一场赌博游戏的图表。

I have a lottery of sorts that the user can bet on. 我有各种各样的用户可以下注的乐透。 There are 6 items the user can buy which each have 6 prizes: 用户可以购买6件物品,每件物品有6个奖品:

在此输入图像描述

These can be put into objects or arrays. 这些可以放入对象或数组中。

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

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

I'm trying to create a chart that calculates how much money you would have to spend on each particular item per game to guarantee you gain money - for 300 games out. 我正在尝试创建一个图表,计算每场比赛每件特定物品需要花多少钱来保证你获得金钱 - 在300场比赛中。

So here is an example of how the chart should start off: 以下是图表应如何开始的示例:

在此输入图像描述

investment = max possible winnings + total spent( which is negative ) 投资=最大可能的奖金+总花费(这是负数)

The 2nd row is assuming the first game already happened and lost. 第二排假设第一场比赛已经发生并输了。 And so on. 等等。

The idea is to start with the smallest item but give up once it can no longer get you positive even if you win. 我们的想法是从最小的项目开始,但即使你赢了也不会再让你积极的东西放弃。 This is why on row 9 we switch to the rock . 这就是为什么在第9排我们切换到岩石 ( our investment is at 0 and if we play a twig again, the most we can win is 40. So even if we did win, we would actually have lost 5 overall. ) (我们的投资是0,如果我们再次投球,我们赢得的最多就是40个。所以即使我们赢了,我们实际上也会输掉5个。)

Also worth pointing out is that if you win on 1 item; 另外值得指出的是,如果你赢了1项; you win on all items for that particular game. 你赢得了特定游戏的所有项目。 So you get all prizes combined. 所以你可以获得所有奖品。

I've been working on this for a few days now and some of these related questions have my initial attempts ( but I honestly have no idea ): 我一直在研究这几天,其中一些相关的问题是我最初的尝试(但老实说我不知道​​):

How to find the lowest possible combination of keys within an array 如何在阵列中找到尽可能低的键组合

Counter that generates the lowest sum from a combination of indexes above the previous value 从上一个值之上的索引组合生成最低总和的计数器

Add an arrays keys to themselves until exceeding a limit? 添加数组密钥直到超出限制?

EDIT: At least 1 item(s) must be bought every game and games cannot be skipped 编辑:每场比赛必须至少购买1件商品,不能跳过游戏

Basically this proposal relies on a function to get the next items 基本上这个提议依赖于获取下一个项目的功能

    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;
        }
    }(),

which starts at price with zero and increments the value by one until a combination of items is found. 以零开始于价格并将值递增1,直到找到项目组合。 Then the items array is returned. 然后返回items数组。 The function works as generator. 该功能用作生成器。

The other important function is the combination of items with a given price and the try to get an array with the items. 另一个重要的功能是具有给定价格的项目的组合以及尝试获得具有项目的数组。

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 takes an array with prices and a wanted sum to reach with combinating the given prices. combine收集数组与价格和想要的总和达到组合给定的价格。 If successfull, an array with the items is returned, otherwise an empty array. 如果成功,则返回包含项的数组,否则返回空数组。

The third part is to use the items as long as the investment is not negative. 第三部分是使用项目,只要投资不是负面的。 If that happens, a new items set is fetched. 如果发生这种情况,则会获取新的项目集。

 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; } 

Here is my 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> 

You can create an object where property names are set the values of possibleWins . 您可以创建一个对象,其中属性名称设置为possibleWins的值。 Set all of the possible combinations of investing the limit at each round. 设置在每轮投资限额的所有可能组合。 The arrays do not contain all possible combinations of numbers less than the limit for that particular round. 数组不包含小于该特定回合限制的所有可能的数字组合。 That is, the numbers are not dispersed in every possible combination. 也就是说,数字不会分散在每种可能的组合中。 For example, at round 40 , [10, 10, 10, 10, 0, 0, 0, 0] is included as an array; 例如,在第40轮,包括[10, 10, 10, 10, 0, 0, 0, 0]作为数组; though the array could also be rearranged to [10, 0, 10, 10, 0, 10, 0, 10] , or other combination of indexes totaling less than 40 . 虽然阵列也可以重新排列为[10, 0, 10, 10, 0, 10, 0, 10] 10,0,10,10,0,10,0,10 [10, 0, 10, 10, 0, 10, 0, 10] ,或者总和小于40其他索引组合。

Additional of the possible allowed combinations less than the limit for that round be pushed to the array corresponding a specific round at the returned object. 将小于该轮limit的可能允许组合的其他组合推送到对应于返回对象处的特定轮的阵列。

This implementation does not attempt to locate the selection routes of each round which would lead to a positive outcome. 该实现不会尝试定位每轮的选择路线,这将导致积极的结果。 The entire set of arrays can be iterated as to each matching index in each array, combination of random indexes, or every possible combination of indexes. 可以针对每个数组中的每个匹配索引,随机索引的组合或每个可能的索引组合来迭代整个数组集。

The approach is a base template from which possible selections can be made. 该方法是一个基本模板,可以从中进行选择。 Further optional arrays containing combinations of values less object property name, that is the particular round, or values within arrays from within arrays at properties of object having a property name value less than the current round, can be added to the array of arrays; 包含值的组合的更多可选数组,即对象属性名称,即特定的一轮,或者数组内的值,在属性名称值小于当前轮次的对象的属性中,可以添加到数组数组中; to find the combinations of selections which lead to the expected outcome. 找到导致预期结果的选择组合。

 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); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM