Wednesday, April 23, 2008 3:44:34 AM UTC #

If you aren't already in the know, these ten problems are from the 2008 Winter Scripting games.

For each problem, I'm going to quickly sum up the interesting (interesting TO ME) bits of each problem, then I'm going to post the full source.

Event 3: Instant (Runoff) Winner

 

This is not as straightforward as it looks. We are presented with a list of votes, each person voting for their preferred candidates, in order of preference. For each vote, you need to first count them as if there are 4 candidates, then count as if there are 3, then 2, until a candidate gets the majority vote. I'm actually proud of my solution. Some of the awesomeness is embodied in the following representative line:

$runoffCandidates = $results | Sort Percent -desc | select -first ($results.Count - 1) | % { $_.Name }

This is the magic that removes the candidate who just got booted off the island by reconstructing the list of the surviving candidates.

Source

#PROBLEM #3

#global, will change as the runoff eliminates candidates.
$runoffCandidates = @("Ken Myer","Jonathan Haas","Pilar Ackerman","Syed Abbas")

#POSTSCRIPT - this is one of the few times I think I'm justified in making a scriptmethod,
#because I think this is a nice solution to the problem.
function Create-VoteObject ($rawData)
{
    $o = new-object PSObject
    Add-Member -inputObject $o -memberType NoteProperty -name "Votes" -value $rawData.Split(",")
    Add-Member -inputObject $o -memberType ScriptMethod -name "GetValidVote" -value { Get-FirstValidCandidate $this.Votes }


    $o
}


function Get-FirstValidCandidate ($votes)
{
    foreach ($candidate in $votes)
    {
        if ($runoffCandidates -contains $candidate)
        {
            return $candidate
        }
    }
   
    #impossible to get here, throw error
    Throw "ERROR: Get-FirstValidCandidate should have already returned a value before reaching this point."
}

function Read-Votes ($filename)
{
    $rawVotes = cat $filename

    $rawVotes | % { Create-VoteObject -rawData $_ }
}

function Solve-Problem3
{
    $votes = Read-Votes "C:\Scripts\votes.txt"
   
    while ($runoffCandidates.Count -ge 2) {
        #POSTSCRIPT: to be honest, I think I originally wrote the following line as a function, then "shrunk
        #it down" to the following line. I'll break it up into each element in the pipeline:
        #    $results = $votes |
        #        Select @{ Name="Candidate"; Expression={ $_.GetValidVote() } } |
        #        group Candidate |
        #        select Name,
        #            @{ Name="Percent"; Expression={($_.Count/$votes.Count) * 100 } },
        #            @{ Name="Victory"; Expression={($_.Count/$votes.Count) -ge .5 } }
        $results = $votes | Select @{ Name="Candidate"; Expression={ $_.GetValidVote() } } | group Candidate | select Name, @{ Name="Percent"; Expression={($_.Count/$votes.Count) * 100 } }, @{ Name="Victory"; Expression={($_.Count/$votes.Count) -ge .5 } }
        $victoriousCandidate = $results | ? { $_.Victory }
        if ($victoriousCandidate)
        {
            write-host "The winner is $($victoriousCandidate.Name) with $($victoriousCandidate.Percent)% of the vote."
            break
        } else
        {
            $runoffCandidates = $results | Sort Percent -desc | select -first ($results.Count - 1) | % { $_.Name }
        }
    }
}


Solve-Problem3

2008 Winter Scripting Game Events: Index

Categories: PowerShell
Technorati:
Name
E-mail
Home page

Comment (Some html is allowed: b, blockquote@cite, em, i, strike, strong, sub, sup, u) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview
Syndication

Search
Posts on this page
Categories
Sites I visit regularly
About

Powered by: newtelligence dasBlog 2.2.8279.16125

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2013, Peter Seale

Send mail to the author(s) E-mail



Sign In