public Roster Run(IEnumerable <Player> players) { var orderedPlayers = players.GroupBy(p => p.Position) .ToDictionary(p => p.Key, g => g.OrderByDescending(p => p.Projection).ToArray()); var roster = new Roster(); roster.Add(orderedPlayers["QB"].First()); roster.Add(orderedPlayers["RB"].Skip(1).First()); roster.Add(orderedPlayers["RB"].Skip(2).First()); roster.Add(orderedPlayers["WR"].Skip(1).First()); roster.Add(orderedPlayers["WR"].Skip(2).First()); roster.Add(orderedPlayers["WR"].Skip(3).First()); roster.Add(orderedPlayers["TE"].First()); roster.Add(orderedPlayers["DST"].First()); var flexOptions = orderedPlayers["RB"].Union(orderedPlayers["WR"]).Union(orderedPlayers["TE"]) .OrderByDescending(p => p.Projection); foreach (var flex in flexOptions) { if (roster.CanAdd(flex)) { roster.Add(flex); break; } } var allTopPlayersOrdered = players .GroupBy(p => p.Position) .SelectMany(g => g.Where(p => p.Projection > Percentile(g, 50))) .OrderByDescending(p => p.Salary).ToArray(); int index = 0; while (roster.Salary > 50000) { var newPlayer = allTopPlayersOrdered[index]; if (!roster.Contains(newPlayer)) { var mostExpensiveAtPosition = roster .Where(p => p.Position == newPlayer.Position) .OrderByDescending(p => p.Salary) .First(); if (mostExpensiveAtPosition.Salary > newPlayer.Salary) { roster.Remove(mostExpensiveAtPosition); roster.Add(newPlayer); } } index++; } return(roster); }
public Roster Run(IEnumerable <Player> players) { var orderedPlayers = players.GroupBy(p => p.Position) .ToDictionary(p => p.Key, g => g.OrderByDescending(p => p.Projection).ToArray()); var perfectRoster = new Roster(); perfectRoster.Add(orderedPlayers["QB"].First()); perfectRoster.Add(orderedPlayers["RB"].Skip(1).First()); perfectRoster.Add(orderedPlayers["RB"].Skip(2).First()); perfectRoster.Add(orderedPlayers["WR"].Skip(1).First()); perfectRoster.Add(orderedPlayers["WR"].Skip(2).First()); perfectRoster.Add(orderedPlayers["WR"].Skip(3).First()); perfectRoster.Add(orderedPlayers["TE"].First()); perfectRoster.Add(orderedPlayers["DST"].First()); var flexOptions = orderedPlayers["RB"].Union(orderedPlayers["WR"]).Union(orderedPlayers["TE"]) .OrderByDescending(p => p.Projection); foreach (var flex in flexOptions) { if (perfectRoster.CanAdd(flex)) { perfectRoster.Add(flex); break; } } var roster = perfectRoster.Clone(); var skips = new List <Player>(); var irreplaceablePositions = new List <string>(); double goal = 50000; while (roster.Salary > goal) { var leastEfficentOnRoster = roster .Where(p => !irreplaceablePositions.Contains(p.Position)) .OrderBy(p => p.PointPerCost) .First(); var newPlayer = players .Where(p => p.Position == leastEfficentOnRoster.Position) .Where(p => p.Salary < leastEfficentOnRoster.Salary) .Except(skips) .OrderByDescending(p => p.Projection) .FirstOrDefault(); if (newPlayer == null) { irreplaceablePositions.Add(leastEfficentOnRoster.Position); } else if (roster.Contains(newPlayer)) { skips.Add(newPlayer); } else { roster.Remove(leastEfficentOnRoster); roster.Add(newPlayer); } } return(roster); }
public IEnumerable<Roster> Permutations(IEnumerable<Player> players) { var byPos = players .GroupBy(p => p.Position) .ToDictionary( g => g.Key, g => { if (new[] { "QB" }.Contains(g.Key)) { return g.ToArray(); } else if (g.Key == "DST") { return g.OrderByDescending(p => p.Projection).Take(3).ToArray(); } else { return g.Where(p => p.Projection > 10d).ToArray(); } }); var flexes = byPos["RB"].Concat(byPos["WR"]).ToArray(); var rosters = new ConcurrentDictionary<Roster, byte>(); int limit = 20; Roster lowest = new Roster(); double index = 0; double count = flexes.Length * byPos["QB"].Length * byPos["TE"].Length * byPos["DST"].Length * (byPos["RB"].Length - 1) * (byPos["RB"].Length - 1) * (byPos["WR"].Length - 2) * (byPos["WR"].Length - 2) * (byPos["WR"].Length - 2); Parallel.ForEach(flexes, new ParallelOptions { MaxDegreeOfParallelism = 7 }, flex => { foreach (var qb in byPos["QB"]) { foreach (var te in byPos["TE"]) { foreach (var dst in byPos["DST"]) { var rbs = byPos["RB"]; var wrs = byPos["WR"]; for (int iRb1 = 0; iRb1 < rbs.Length - 1; iRb1++) { for (int iRb2 = 1; iRb2 < rbs.Length; iRb2++) { for (int iWr1 = 0; iWr1 < wrs.Length - 2; iWr1++) { for (int iWr2 = 1; iWr2 < wrs.Length - 1; iWr2++) { for (int iWr3 = 2; iWr3 < wrs.Length; iWr3++) { ++index; if (Progress != null && index % 100000d == 0) { Progress(this, index / count); } var dupeChecker = new HashSet<Player>(); dupeChecker.Add(flex); if (!dupeChecker.Add(rbs[iRb1]) || !dupeChecker.Add(rbs[iRb2]) || !dupeChecker.Add(wrs[iWr1]) || !dupeChecker.Add(wrs[iWr2]) || !dupeChecker.Add(wrs[iWr3])) { continue; } var roster = new Roster(); roster.Add(qb); roster.Add(te); roster.Add(flex); roster.Add(dst); roster.Add(rbs[iRb1]); roster.Add(rbs[iRb2]); roster.Add(wrs[iWr1]); roster.Add(wrs[iWr2]); roster.Add(wrs[iWr3]); if (roster.Salary > 50000) continue; if (rosters.Count < limit) { if (rosters.TryAdd(roster, 0)) { lowest = rosters.Keys.OrderBy(r => r.Projection).First(); } } else if (roster.Projection > lowest.Projection) { rosters.TryAdd(roster, 0); if (rosters.Count > limit) { rosters.TryRemove(lowest, out byte z); } lowest = rosters.Keys.OrderBy(r => r.Projection).First(); } } } } } } } } } }); return rosters.Keys; }