Sunday, February 24, 2008

2008 Scripting Games, Solution 3

# Advanced Event 3: Instant (Runoff) Winner
# http://www.microsoft.com/technet/scriptcenter/funzone/games/games08/aevent3.mspx

# Load all votes from the file
$allvotes=type c:\scripts\votes.txt

# While-true in lack of a real do-loop construct
while ($true) {
# Pick up the first name from each line
$votes=$allvotes | ? {$_} | % {$vote,$null=$_.split(","); $vote }
# Save the count
$count=$votes.count
write-verbose "count=$count"
# Use Group combined with select and a calculated property to get percentages
$result=$votes | Group | Select Name,@{Name="Percentage";Expression={$_.count / $count * 100}}
# Do we have a winner? If a percentage is larger than 50, we do
if (($result | measure-object -Maximum Percentage).Maximum -gt 50) {
# Get winner, only one can be returned
$winner=$result | ? {$_.Percentage -gt 50}
# Format output as requested
"The winner is $($winner.name) with $($winner.percentage.tostring('##.#'))% of the vote."
# Exit while
break
}
write-verbose "Winner not found"
# Find candidate that needs to be eliminated
$fewestVotes=$result | sort Percentage | Select -First 1
write-verbose "Fewest votes $fewestVotes"
# Modify votes by removing candidate with fewest votes
# Each line is turned into an array, the array is converted back into
# a comma-separated line excluding the candidate
# Note how -ne can be used to remove values from a collection/array
$allvotes=$allvotes | % {
$votes=$_.split(",")
[string]::join(",",$votes -ne $fewestVotes.Name)
}
}

No comments: