20. February 2008
I thought event 2 was pretty cool. We have to take in a list of figure skaters and their scores, drop the highest and lowest score, average them, and assign a gold, silver and bronze medal to the top three competitors.
This problem was extremely conducive to using the power of the pipeline in Powershell.
1: $competitors = Get-Content c:\scripts\skaters.txt
2: [array]$totalScores = "" | Select-Object Name,Score,Medal
4: foreach ($competitor in $competitors)
6: $scores = "" | Select-Object Name,Score,Medal
7: $scores.Name,$scores.Score = $competitor.Split(",")
8: $stats = $scores.Score | Measure-Object -Maximum -Minimum
9: $scores.Score = $scores.Score -replace $stats.Maximum
10: $scores.Score = $scores.Score -replace $stats.Minimum
11: $scores.Score = [math]::Round(($scores.Score | Measure-Object -Average).Average,2)
12: $totalScores += $scores
14: $winners = $totalScores | Sort-Object Score -Descending | Select-Object -First 3 $winners.Medal,$winners.Medal,$winners.Medal = "Gold","Silver","Bronze"
15: $winners | Format-Table -AutoSize
First we pull in the contents of the skaters.txt file. Next I use a little shortcut to create a custom PSObject using select-object. This creates a PSObject with three properties, a Name, a Score, and a Medal. This will become a collection of scores objects.
Using a foreach loop, we go through each competitor and create a new score object, assigning its values.Name to the name of the competitor and then the scores as an array in the .score property.
Please check out my post on multi variable assignment to see how this works.
I can pull the minimum and maximum using measure object and drop them. After that I use measure-object again to take the average and stuff it in the .score property.
I should mention here that /\/\o\/\/'s solution was pretty darn slick. I loved how he sorted and then select 1..5, essentially dropping the top and bottom score before he took the average.
The final item is to add the current score object to the collection of score objects called $totalScores.
Now it becomes quite easy to get the winners. We just sort the $totalScores collection by Score, select the top 3, and assign their .medal value accordingly.
Multi variable assignment is so cool. Ever since I found out about it it seems to appear in everything I do.
Have fun Powershelling