/// <summary> /// Gets the winning vote. /// Excludes any already chosen votes from the process. /// </summary> /// <param name="voterRankings">The voter rankings.</param> /// <param name="chosenChoices">The already chosen choices.</param> /// <param name="allChoices">All remaining choices.</param> /// <returns>Returns the winning vote.</returns> /// <exception cref="System.ArgumentNullException"> /// </exception> private RankResult GetWinningVote(IEnumerable <VoterRankings> voterRankings, RankResults chosenChoices, List <string> allChoices) { if (voterRankings == null) { throw new ArgumentNullException(nameof(voterRankings)); } if (chosenChoices == null) { throw new ArgumentNullException(nameof(chosenChoices)); } // Initial conversion from enumerable to list List <VoterRankings> localRankings = RemoveChoicesFromVotes(voterRankings, chosenChoices.Select(c => c.Option)); AddUnselectedRankings(localRankings, allChoices); int voterCount = localRankings.Count(); int winCount = voterCount / 2 + 1; string eliminated = ""; bool eliminateOne = false; while (true) { var preferredVotes = GetPreferredCounts(localRankings); if (!preferredVotes.Any()) { break; } ChoiceCount best = preferredVotes.MaxObject(a => a.Count); if (best.Count >= winCount) { return(new RankResult(best.Choice, $"Coombs Eliminations: [{eliminated}]")); } // If no more choice removals will bump up lower prefs to higher prefs, return the best of what's left. if (!localRankings.Any(r => r.RankedVotes.Count() > 1)) { return(new RankResult(best.Choice, $"Coombs Eliminations: [{eliminated}]")); } eliminated += Comma(eliminateOne); string leastPreferredChoice = GetLeastPreferredChoice(localRankings); eliminated += leastPreferredChoice; RemoveChoiceFromVotes(localRankings, leastPreferredChoice); eliminateOne = true; } return(null); }
/// <summary> /// Reads the user's choice input. /// </summary> /// <param name="index">The output choice index. -1 if invalid.</param> /// <returns>True if the choice was valid.</returns> protected bool ReadChoice(out int index) { if (ChoiceCount == 1) { Console.Write("Press Enter: "); } else { Console.Write($"Enter choice ({1}-{ChoiceCount}): "); if (acceptNoInput) { PrintWatermark(ChoiceCount.ToString()); } } return(IsValidChoice(Console.ReadLine(), out index)); }