Оптимизация списка спортивных соревнований с помощью запроса LINQ или аналогичного подхода - PullRequest
1 голос
/ 23 марта 2020

Я пытаюсь построить функцию, которая будет оптимизировать результат для спортсменов, участвующих в соревнованиях. Допустим, у меня есть класс спортсмена:

public class Athlete
{
    public int ID {get; set; }
    public string Name { get; set; }
    public int RunningAbility { get; set; }
    public int SwimmingAbility { get; set; }

    public readonly List<Attempt> { get; set; }
}

Каждый спортсмен делает 2 попытки в соревновании. Они могут соревноваться в плавании два раза, бегать два раза или могут выполнять по одному. Единственное условие - количество бегунов и пловцов должно быть одинаковым; поэтому, если было 3 спортсмена, нужно сделать 6 попыток - 3 бега и 3 плавания.

Класс Попытки выглядит следующим образом:

public class Attempt
{
    public string AthleteID { get; set; }
    public string EventName { get; set; }
}

Я застрял, пытаясь понять, как составить список попыток с наилучшим из возможных сценариев.

public void Main(){
    var people = new List<Athlete>() {
        new Athlete()
        {
            Name = "Bob",
            RunningAbility = 10,
            SwimmingAbility = 10
        },
        new Athlete()
        {
            Name = "Joe",
            RunningAbility = 8,
            SwimmingAbility = 2
        },
        new Athlete()
        {
            Name = "Sue",
            RunningAbility = 3,
            SwimmingAbility = 7
        },
    };

    var attempts = GetBestPossible(people);
}

private List<Attempt> GetBestPossible(List<People> people)
{
    var attempts = new List<Attempt>();
    //Each Person must compete twice and can either use both attempts in same event or one in each event
    //The entire team Must have equal attempts for running and swimming - i.e. 3 attempt swimming and 3 attempts running in this case.
    //How would I make a linq query or comparable solution on people that would give me a 
    //list of attempts with the max ability utilized for both events?
    //Expected outcome for attempts list would be 
    //Name  Event
    //Bob   Running
    //Bob   Swimming
    //Joe   Running
    //Joe   Running
    //Sue   Swimming
    //Sue   Swimming

    //Meets criteria of having each Person attempt twice 
    //and equal attempts in both events with MAX ability

    return attempts;
}

Кто-нибудь знает, есть ли способ сделать это с Linq или это невозможно с данными подробностями? Я не уверен, с чего начать, так что любая помощь очень ценится!

РЕДАКТИРОВАТЬ: Добавлено свойство List<Attempt> в мой класс Person, я все еще не уверен, как я могу решить свою проблему, но Я думаю, что мне нужно написать функцию, которая просматривает все возможные результаты для каждого экземпляра спортсмена, а затем подсчитывает и каким-то образом определяет, какой из результатов является лучшим для обоих событий.

1 Ответ

1 голос
/ 25 марта 2020

Вот кое-что, что, мы надеемся, так или иначе поможет решить проблему.

У вас есть две игры / соревнования, давайте создадим для них enum:

//...
public enum Competitions { Running, Swimming }
//...

Класс Attempt, макс. два экземпляра этого объекта для каждого Athlete независимо от типов соревнований.

//...
public class Attempt
{
    public Competitions Competition { get; set; } 
    public int Score { get; set; }
}
//...

Класс Athlete:

//...
public class Athlete
{       
    public string Name { get; set; }

    public readonly List<Attempt> Attempts = new List<Attempt>();

    public override string ToString() => Name;
}
//...

И еще один класс, который будет отчетом / запись статистики / статуса (назовите ее) для каждого спортсмена.

//...
public class Statistics
{
    public string Name { get; set; }
    public int Running { get; set; }
    public int Swimming { get; set; }
    public int TotalScore { get => Running + Swimming; }
    public int RunningRank { get; set; }
    public int SwimmingRank { get; set; }
    public int GeneralRank { get; set; }
}
//...

В вашей реализации у вас есть List<Athlete>, заполненный некоторыми записями, например:

//...
List<Athlete> Athletes = new List<Athlete>();

private void CreateList()
{
    Athletes.Clear();

    var jim = new Athlete { Name = "Jim" };
    jim.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 1 });
    jim.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 2 });

    var joe = new Athlete { Name = "Joe" };
    joe.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 7 });
    joe.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 2 });

    var sue = new Athlete { Name = "Sue" };
    sue.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 3 });
    sue.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 7 });

    var bob = new Athlete { Name = "Bob" };
    bob.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 10 });
    bob.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 10 });

    var ben = new Athlete { Name = "Ben" };
    ben.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 5 });

    var sam = new Athlete { Name = "Sam" };
    sam.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 6 });
    sam.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 4 });

    Athletes.AddRange(new[] { jim, joe, sue, bob, ben, sam });
}
//...

Сейчас давайте создадим статистику или отчет для каждого члена , где сумма их попыток бега и плавания равна.

//...
private IEnumerable<Statistics> CreateStatistics()
{
    var ath = Athletes.Where(x => x.Attempts.Count() == 2
    && x.Attempts.First().Competition != x.Attempts.Last().Competition);

    var abi = (from a in ath
                select new Statistics
                {
                    Name = a.Name,
                    Running = a.Attempts
                    .First(r => r.Competition == Competitions.Running).Score,
                    Swimming = a.Attempts
                    .First(s => s.Competition == Competitions.Swimming).Score,
                }).ToList();

    foreach (var a in abi)
    {
        a.RunningRank = 1 + abi.Select(r => r.Running).OrderByDescending(r => r)
            .ToList().IndexOf(a.Running);

        a.SwimmingRank = 1 + abi.Select(s => s.Swimming).OrderByDescending(s => s)
            .ToList().IndexOf(a.Swimming);

        a.GeneralRank = 1 + abi.Select(t => t.TotalScore).OrderByDescending(t => t)
            .ToList().IndexOf(a.TotalScore);
    }

    return abi;
}
//...

Результат:

SOQ60819266

Как вы можете видеть, запрос выбрал только трех участников из списка и создал запись статистики для каждого, которая показывает их очки и вычисляет их ранги для каждой игры, а также общее или общее звание.

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...