Divide x into y parts by decreasing amount

后端 未结 3 2087

If I had $1000(variable) and I want to split that amount up and give it to 20(variable) people, but rather than give it evenly to each person, I want to give more to the 1st per

3条回答
  •  我在风中等你
    2021-01-25 22:35

    You owe me a beer, actually a chug of beer!!

    Using Gauss distribution (N*(N+1))/2 you cannot have a slight margin over the competitors ranks, prizes have linear increase https://mathbitsnotebook.com/Algebra2/Sequences/SSGauss.html.

    What you need is something that increases exponentially or with a fixed ration, I want to solve your problem with a mathematical approach, so I will use a geometric progression https://mathbitsnotebook.com/Algebra2/Sequences/SSGeometric.html

    I won't add any other answer after this one, you have to build your own prize pool system!!

    For Geometric Distribution formula is:

    rankPrize = ((1 - distributionFactor) / (1 - distributionFactor ^ winners) * distributionFactor ^ (rank - 1)) * prize

    where distributionFactor - is between 0 and 1

    Play around with distribution Factor and chose the correct value for your system, I've chosen 0.8 because the gap between prizes is not that big!

    Here we go, fiddle link: https://dotnetfiddle.net/qmJnYd to play around and implementation:

    static void GaussDistributionPricePool()
            {
                Console.WriteLine("________________________________________________________");
                Console.WriteLine("Begin Gauss distribution price pool");
    
                int totalPeople = 20;
                float prize = 5000;
    
                List peopleScores = new List();
                Random r = new Random();
                for (int i = 0; i < totalPeople; ++i)
                {
                    peopleScores.Add(r.Next(0, 100));
                }
    
                var totalPeopleWithScore = peopleScores.Where(x => x > 0).Count();
    
                var groupedScores = peopleScores
                    .Where(x => x > 0)
                    .ToList()
                    .GroupBy(x => x)
                    .Select(grp => new
                    {
                        score = grp.Key,
                        peopleScores = grp.ToList()
                    })
                    .OrderBy(g => g.score)
                    .ToList();
    
                var groupCount = groupedScores.Select(x => new { count = x.peopleScores.Count() }).Select(z => z.count).Count();
                // Gauss formula. (N*(N+1))/2
                // https://mathbitsnotebook.com/Algebra2/Sequences/SSGauss.html
                float basePrizeRate = 2 * prize / totalPeopleWithScore / (totalPeopleWithScore + 1);
                Console.WriteLine("Base Price rate: " + basePrizeRate);
                float sum = 0;
                var leaderboardRank = 0;
                var totalWinners = 0;
                foreach (var positionScore in groupedScores)
                {
                    var countWinner = positionScore.peopleScores.Count();
                    Console.WriteLine();
                    Console.WriteLine("On leaderboard rank : " + (groupedScores.Count() - leaderboardRank) + " are " + countWinner + " winners with score: " + positionScore.score);
    
                    float positionPrizePool = 0;
                    for (int i = 1; i <= positionScore.peopleScores.Count(); ++i)
                    {
                        totalWinners++;
                        positionPrizePool += totalWinners * basePrizeRate;
                    }
                    Console.WriteLine("Prize Pool " + positionPrizePool);
                    var personPoolPrize = positionPrizePool / positionScore.peopleScores.Count();
                    foreach (var x in positionScore.peopleScores)
                    {
                        Console.WriteLine("Winner " + totalWinners + " won: " + personPoolPrize);
                        sum += personPoolPrize;
                    }
                    leaderboardRank++;
                }
                Console.WriteLine();
    
                Console.WriteLine("Total Prize: " + sum);
                Console.WriteLine("Total Winners: " + totalPeopleWithScore);
    
                Console.WriteLine("End Gauss distribution price pool");
                Console.WriteLine("________________________________________________________");
            }
    

提交回复
热议问题