Scripting Games: Event 1/Beginner/PowerShell
Well, the first events of the scripting games are over and the solutions are up on the Script Center now, so here begins my tradition of around this time of year of putting my solutions up contemporaneously with the official ones - mostly because they're often at significant variance from the Official Solutions, and it's always nice to see other ways to do things.
Anyway, this is the PowerShell solution to Beginner Division Event 1: Pairing Off. You can read the scenario here, and the official solution is here. Mine was:
# Beginner Division, Event 1: Pairing Off
# A card is defined as a pair of values, the first representing
# the suit, the second representing the value.
#
# For the purposes of this encoding, the suits are as follows:
#
# Hearts = 0
# Spades = 1
# Clubs = 2
# Diamonds = 3
#
# Card ranks:
#
# Ace = 1, Jack = 11, Queen = 12, King = 13
# The cards we are using are given in the problem definition:
#
# Seven of spades, Five of hearts, Seven of diamonds, Seven of
# clubs, King of clubs
$cards = ((1, 7), (0, 5), (3, 7), (2, 7), (2, 13))
# Technically, we needn't have bothered storing the suits; we
# can look for pairs using nothing but the card rank. On the
# other hand, let's just do a little extra work here and validate the
# card array we've got, to be sure.
$valid = new-object System.Collections.ArrayList ($cards.Length)
# Basically, duplicate cards should never happen, since they're being
# dealt off a standard deck. So we check for that, and then keeping
# the suit information around is worthwhile.
foreach ($card in $cards)
{
# Compute crude unique card value
$ucv = $card[0].ToString() + ":" + $card[1].ToString()
# Check if the card is present in the validation ArrayList
if ($valid.Contains($ucv))
{
Throw ("Duplicate card: " + $ucv)
}
# Add each card to the ArrayList, after the check.
$null = $valid.Add($ucv)
}
# OK, enough of this frivolity. Time to do the actual challenge, and
# compare the card pairs.
#
# Here's what we're doing. Take each card one at a time, and then
# go through the rest of the deck and count any pairs containing
# that card. Then throw that card away, since all possible pairs
# have been counted, and repeat using the remaining deck.
#
# Actually works on lists of arbitrary length, which exceeds the spec,
# but who's counting?
$pairCount = 0
if ($cards.Length -gt 1)
{
while ($cards.Length -gt 2)
{
# split into the first card and the remaining
# cards
$first, $rest = $cards
foreach ($card in $rest)
{
if ($first[1] -eq $card[1])
{
$pairCount++
}
}
$cards = $rest
}
# when we get here, there are exactly two cards left
# we do this here because $rest ends up as a
# one-dimensional array when split in the above
# routine and $cards.Length == 2.
#
# It's a workaround workaround, basically.
if ($cards[0][1] -eq $cards[1][1])
{
$pairCount++
}
}
Write-Host "There are" $pairCount "pairs."
Well, obviously that's a good bit longer than the official one, mostly because of the frivolously thrown-in validation routine to make use of the suit information we were provided with - even though, as they point out, that's not required by the spec. That, and I prefer foreach to for for iterating collections, particularly since that lets it work on card-sets of arbitrary length, even though that's not required by the spec either.
What can I say? I guess I hate writing overspecialized code.
Categories
Technology & Progress0 TrackBacks
Listed below are links to blogs that reference this entry: Scripting Games: Event 1/Beginner/PowerShell.
TrackBack URL for this entry: http://weblog.siliconcerebrate.com/mt/mt-tb.cgi/1010
Also see here: http://weblog.siliconcerebrate.com/cerebrate/2008/02/scripting-games-in-haskell.html