Разделите х на у частей по убыванию - PullRequest
0 голосов
/ 28 мая 2019

Если у меня было $ 1000 (переменная), и я хочу разделить эту сумму и дать ее 20 (переменным) людям, но вместо того, чтобы распределять ее равномерно по каждому человеку, я хочу дать больше 1-му человеку, и2-й человек и т. Д.

Таким образом, 20-й человек получает наименьшее количество, а 5-й - 5-е место.

Как бы мне этого добиться?

Спасибо

Редактировать:

Формула:

int people = 20;
float prize = 1000;

float k = (2 * prize) / ((people) * (people - 1));
float sum = 0;

for (int i = 1; i < people; ++i)
{
    var personsPrize = i * k;
    sum += personsPrize;
    Console.WriteLine(personsPrize);
}
Console.WriteLine("sum = " + sum);

Ответы [ 3 ]

1 голос
/ 28 мая 2019

Формула верна, нужно немного коснуться.

  1. Не бросайте float в int, потеря данных!
  2. При переходе в for с первого ходачеловек к н-1

    int people = 20;
    float prize = 1000;
    
    float k = (2 * prize) / ((people) * (people - 1));
    float sum = 0;
    
    for (int i = 1; i < people; ++i)
    {
        var personsPrize = i * k;
        sum += personsPrize;
        Console.WriteLine(personsPrize);
    }
    Console.WriteLine("sum = " + sum);
    
0 голосов
/ 29 мая 2019

Вы должны мне пиво, на самом деле пиво! !!

Используя распределение Гаусса (N * (N + 1)) / 2, вы не можете иметь небольшое преимущество над рангами конкурентов, призы имеют линейное увеличение https://mathbitsnotebook.com/Algebra2/Sequences/SSGauss.html.

Вам нужно что-то, что увеличивается экспоненциально или с фиксированным рационом, я хочу решить вашу проблему с помощью математического подхода, поэтому я буду использовать геометрическую прогрессию https://mathbitsnotebook.com/Algebra2/Sequences/SSGeometric.html

После этого ответа я не буду добавлять никаких других ответов, вам нужно создать собственную систему призового фонда !!

Для геометрического распределения формула:

rankPrize = ((1 - distributionFactor) / (1 - distributionFactor ^ победители) * distributionFactor ^ (rank - 1)) * выигрыш

, где distributionFactor - от 0 до 1

Поиграйте с Фактором распределения и выберите правильное значение для вашей системы, я выбрал 0,8, потому что разрыв между призами не так уж и велик!

Вот, пожалуйста, ссылка на скрипку: https://dotnetfiddle.net/qmJnYd, чтобы поиграться и реализовать:

static void GaussDistributionPricePool()
        {
            Console.WriteLine("________________________________________________________");
            Console.WriteLine("Begin Gauss distribution price pool");

            int totalPeople = 20;
            float prize = 5000;

            List<int> peopleScores = new List<int>();
            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("________________________________________________________");
        }
0 голосов
/ 28 мая 2019

Добавление ответа к Убедитесь, что призовой фонд не присуждает привязанным участникам меньше участников, набравших худший результат

Две вещи

  1. Неправильно, когда присвоение цен начинается с от первого лица до n-1 один человек не получает выигрыш, правильно - от от первого лица до n

  2. Допустимая базовая цена, отмеченная K:

    k = (2 * приз) / ((человек) * (человек + 1))

Теперь ответьте на другой вопрос:

int totalPeople = 20;
float prize = 5000;

List<int> peopleScores = new List<int>();
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();

float basePrizeRate = 2 * prize / totalPeopleWithScore / (totalPeopleWithScore + 1);
Console.WriteLine("Base Price rate: " + basePrizeRate);
float sum = 0;
var leaderboardPosition = 0;
var totalWinners = 0;
foreach (var positionScore in groupedScores)
{
    var countWinner = positionScore.peopleScores.Count();
    Console.WriteLine();
    Console.WriteLine($"On leaderboard position : {groupedScores.Count() - leaderboardPosition} 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;
    }
    leaderboardPosition++;
}
Console.WriteLine();

Console.WriteLine("Total Prize: " + sum);
Console.WriteLine("Total Winners: " + totalPeopleWithScore);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...