Scripting Games, Advanced Event 1, Phone Numbers

Given a seven digit phone number, find a word that can be formed by keying the number into (an almost) standard phone keyboard – T9 Predictive Text style.  Valid words are obtained from a dictionary file.

The trick here was to spot that this was a simple regular expression problem.  If the phone number begins with the digits 23 this must match words in the dictionary that have A, B or C in position one, followed by D, E or F in position 2 and so on.  As a regular expression this is expressed as "^[ABC][DEF]".

The problem then boils down to converting the number into a simple regex and using select-string to find the first match in the dictionary.  Luckily, select-string has a "-list" parameter that (rather strangely IMHO) tells it to return only one result per file.

Four lines of code for a simple 10 points:-)

  1 $number=Read-Host "Enter 7 digit Phone Number"
  2 
  3 $digitstrings="[ABC]","[DEF]","[GHI]","[JKL]","[MNO]","[PRS]","[TUV]","[WXY]"
  4 
  5 0..6|%{$pat=""}{$pat+=$digitstrings[[int][string]$number[$_]-2]}
  6 (select-string "^$pat$" -list -path 'c:\scripts\wordlist.txt').line

Obvious improvements:

The full set of alphabetic characters on a phone could be handled by simply changing the $digitstrings variable to  "[ABC]","[DEF]","[GHI]","[JKL]","[MNO]","[PQRS]","[TUV]","[WXYZ]" .  Arbitrary length phone numbers could be dealt with by changing "0..6" to scan along the complete number.

*UPDATE* Gaurhoth uses the same regex method (http://thepowershellguy.com/blogs/gaurhoth/archive/2008/02/20/games-2008-advanced-event-1-solution.aspx).  I’d initially tried the "Get-content…|Select-string" technique he adopts but (probably unsurprisingly) using the -path option in select-string rather than using get-content to read the file appears orders of magnitude faster:-)  The result from the script above is returned instantly.

Advertisements

4 thoughts on “Scripting Games, Advanced Event 1, Phone Numbers”

  1. Hey Chris!Could you explain to me why using select-string with the -path option is so much quicker? By the way, I don\’t think you need the [int] in [[int][string]$number[$_]-2].Best regards!

  2. Hi Chris,
     
    Like the way you used the number-2 to index the array of letters. Got to be more efficient than my hashtable of numbers as chars and bits of RegEx pattern.
     
    It\’s great seeing how other people are approaching these challenges differently. It\’s like a high-speed course in advanced PowerShell! ;-)
     
    All the best,
    Jonathan
     
    p.s. I\’m also posting my solutions on Live Spaces. My event 1 is much like this.

  3. Hi Jonathan,
     
    I agree – one of the good things about the games is seeing all the other answers (and hopefully saving some of the techniques in my increasingly mushy brain!)
     
    Looking at your solution, I think between us we have the optimum result!
     
    $d="[ABC]","[DEF]","[GHI]","[JKL]","[MNO]","[PRS]","[TUV]","[WXY]"
    $n.tochararray()|%{$pat=""}{$pat+=$d[[string]$_-2]}
     
    Cheers,
    Chris
     

  4. Hi Bruno,
     
    Get-Content reads each line or the file as a record, converts it to a PS object and adds a whole bunch of additional PowerShell custom properties (slow!)  Using "..gc | select-string…" also has the overhead of the pipeline connection.
     
    Using -path directly on select-string probably uses a highly optimised, low level file-read that avoid all the overheads.  Well, as low-level as you can get with .Net:-)
     
    Try both – the difference is striking.
     
    BTW, thanks about the unnecessary [int] – see optimised method in my other comment :-)
     
    Cheers,
    Chris

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s