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

标签 javascript arrays combinations counter

这似乎有点复杂,所以我会尽我所能尽可能清楚。我正在寻找的特定函数动态创建 钱花|赢钱赌博游戏的图表。

我有各种各样的用户可以下注的彩票。用户可以购买 6 件商品,每件商品有 6 个奖品:

enter image description here

这些可以放入对象或数组中。
var prices = [5,10,28,50,56,280] .
var possibleWins = [40,80,250,400,500,2500]
我正在尝试创建一个图表来计算您必须在每场比赛的每个特定项目上花费多少钱以保证您获得金钱 - 300场比赛。

所以这里是一个图表应该如何开始的例子:

enter image description here

投资=最大可能的奖金+总支出(负数)

第二行假设第一场比赛已经发生并且输了。等等。

我们的想法是从最小的项目开始,但一旦即使你赢了它也不能让你积极,就放弃。这就是为什么在第 9 行我们切换到 摇滚 . (我们的投资是0,如果我们再玩一根 Twig ,我们最多可以赢40。所以即使我们赢了,我们实际上也会输掉5。)

还值得指出的是,如果您在 1 项上获胜;您赢得了该特定游戏的所有项目。因此,您将获得所有奖品。

我已经为此工作了几天,其中一些相关问题有我的初步尝试(但老实说我不知道​​):

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?

编辑:每场比赛必须至少购买一件元素,并且不能跳过比赛

最佳答案

基本上,这个提议依赖于一个函数来获取下一个项目

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

它从零的价格开始,并将值加一,直到找到项目组合。然后 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接受一个包含价格的数组,并通过组合给定的价格来达到想要的总和。如果成功,则返回一个包含项目的数组,否则返回一个空数组。

第三部分是只要投资不是负数就可以使用项目。如果发生这种情况,则会获取一个新的项目集。

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

关于javascript - 跟踪数组内多个值的计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40255189/

相关文章:

javascript - 按频率降序对字符串中的字符进行排序

javascript - 如何将参数传递给 Mongo 脚本

php - 根据两列值和每组中一列的总和对多维数组数据进行分组

arrays - 包含特定索引 'i' 的子数组的数量是多少?

python - 有什么比 itertools 更快的替代品?

javascript - 为什么拼接不填充 javascript 数组上的孔?

javascript - onload 添加类 animate.css

Ruby 多数组比较

java - 按升序对数组元素进行排序

javascript - 组合无重复javascript