簡體   English   中英

計數器跟蹤數組內的多個值

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

這似乎有點復雜,所以我會盡我所能盡可能清楚。我正在尋找的特定功能動態創造了一筆錢。 錢贏了一場賭博游戲的圖表。

我有各種各樣的用戶可以下注的樂透。 用戶可以購買6件物品,每件物品有6個獎品:

在此輸入圖像描述

這些可以放入對象或數組中。

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

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

我正在嘗試創建一個圖表,計算每場比賽每件特定物品需要花多少錢來保證你獲得金錢 - 在300場比賽中。

以下是圖表應如何開始的示例:

在此輸入圖像描述

投資=最大可能的獎金+總花費(這是負數)

第二排假設第一場比賽已經發生並輸了。 等等。

我們的想法是從最小的項目開始,但即使你贏了也不會再讓你積極的東西放棄。 這就是為什么在第9排我們切換到岩石 (我們的投資是0,如果我們再次投球,我們贏得的最多就是40個。所以即使我們贏了,我們實際上也會輸掉5個。)

另外值得指出的是,如果你贏了1項; 你贏得了特定游戲的所有項目。 所以你可以獲得所有獎品。

我一直在研究這幾天,其中一些相關的問題是我最初的嘗試(但老實說我不知道​​):

如何在陣列中找到盡可能低的鍵組合

從上一個值之上的索引組合生成最低總和的計數器

添加數組密鑰直到超出限制?

編輯:每場比賽必須至少購買1件商品,不能跳過游戲

基本上這個提議依賴於獲取下一個項目的功能

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

以零開始於價格並將值遞增1,直到找到項目組合。 然后返回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; } 

這是我的解決方案

 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> 

您可以創建一個對象,其中屬性名稱設置為possibleWins的值。 設置在每輪投資限額的所有可能組合。 數組不包含小於該特定回合限制的所有可能的數字組合。 也就是說,數字不會分散在每種可能的組合中。 例如,在第40輪,包括[10, 10, 10, 10, 0, 0, 0, 0]作為數組; 雖然陣列也可以重新排列為[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其他索引組合。

將小於該輪limit的可能允許組合的其他組合推送到對應於返回對象處的特定輪的陣列。

該實現不會嘗試定位每輪的選擇路線,這將導致積極的結果。 可以針對每個數組中的每個匹配索引,隨機索引的組合或每個可能的索引組合來迭代整個數組集。

該方法是一個基本模板,可以從中進行選擇。 包含值的組合的更多可選數組,即對象屬性名稱,即特定的一輪,或者數組內的值,在屬性名稱值小於當前輪次的對象的屬性中,可以添加到數組數組中; 找到導致預期結果的選擇組合。

 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