>From vlb@cfcl.com Tue Nov 23 01:32:28 1999; sorry for the delay Date: Tue, 23 Nov 1999 09:29:36 -0000 [Note from the listmaster: Folks - please remember this is a closed list. If you aren't a subscriber, your postings come to me. That means if you are subscribed from your home account and post from work, or use an alternate address of any kind those postings fall in my In-box and I get to them when I get to them! I generally add the alternate addresses when that happens, but it can take a few days for things to get through. On the flip side, we see less spam. I now return you to the regular list. - vlb] This is a multi-part message in MIME format. ------=_NextPart_000_001B_01BF3595.41CE46A0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit I may as well give this one a try, it'll be a good learning experience. Please pass comment as this is my first attempt at anything tricky in perl and only fifth script in total, I write C for a living. Paul Livesey p.r.livesey@surfersparadise.net ------=_NextPart_000_001B_01BF3595.41CE46A0 Content-Type: application/octet-stream; name="phonecode.pl" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="phonecode.pl" #!/usr/local/bin/perl -w # ((insert appropriate information replacing each dot)) # Author: Paul R. Livesey # Email: p.r.livesey@surfersparadise.net # Language: Perl # # How long it took to write the program (in minutes): # Design: reading the requirements; deciding on algorithm, # data structure, modularization # Coding: actually writing the program # Test/Debug: trying to get the program to work # ((insert your work times here:)) # Design: In my subconscious for a few days # Coding: 180 - 240 hours # Test/Debug: 60 # # Overall I tend to rate myself as follows compared to all # other programmers (replace one dot by an X): # among the upper 10 percent . # upper 11 to 25 percent X for 'C' # upper 25 to 40 percent . # upper 40 to 60 percent . # lower 25 to 40 percent . # lower 11 to 25 percent X for Perl # lower 10 percent . # # Special events, remarks, insights, constraints etc: # I do nasty things with 'C' for a living, Perl is purely for = recreation. # This is only the fifth thing I've ever written in Perl (please don't # tell my current employer that), so comments and advice are = appreciated. # Most of the time was spent learning the language not solving the = problem. # My first attempt ran like a dog, even on my very fast Sun, so I = rewrote all # of it in about 30 minutes. It is now acceptable. # I suppose a little recursion would be more interesting than my loop = but # it's late. #Better safe than sorry require 5; use strict; use integer; #Function prototype, is this correct? sub do_translations($$); my $dict_file; #Dictionary file my $num_file; #Phone number file my $word; #Current word from dictionary file my $name; #How far we have got in mapping our number my $read_num; #Current number from phone number file my $number; #Current number from phone number file (munged) my %lookup_hash; #Hash of numbers and their words from the dictionary #The following three hashes all contain the initial word mapping as key #and the remaining unmapped phone number as the value my %translations; #Our current hash of things to process my %working_hash; #Our hash of things to process next my %temp_hash; #Our tempory hash of things to process next #Name this was run with $0 =3D~ s(.*[\\/])(); #Correct number of arguments if ( @ARGV !=3D 2 ) { warn "Usage $0 [dictionary file] [phone number file]\n"; exit 1; } #Name of dictionary file $dict_file =3D $ARGV[0]; #Open the dictionary file for reading if ( !open(DICTFILE, $dict_file) ) { warn "$0 : Unable to open $dict_file for reading\n"; exit 1; } #Name of numbers file $num_file =3D $ARGV[1]; #Open the numbers file for reading if ( !open(NUMFILE, $num_file) ) { warn "$0 : Unable to open $num_file for reading\n"; close DICTFILE; exit 1; } #Read in the dictionary, and translate it to a number while ( <DICTFILE> ) { #Remove newline chomp; #Store this word somewhere safe for the moment $word =3D $_; #Remove anything non-alphabetic s/[^a-zA-Z]//og; #Now do the translation from letter to number; s/[Ee]/0/og; s/[JjNnQq]/1/og; s/[RrWwXx]/2/og; s/[DdSsYy]/3/og; s/[FfTt]/4/og; s/[AaMm]/5/og; s/[CcIiVv]/6/og; s/[BbKkUu]/7/og; s/[LlOoPp]/8/og; s/[GgHhZz]/9/og; #Store original word and number representation in a hash #Lookup is by number push @{$lookup_hash{$_}}, $word; } close DICTFILE; #Now read in numbers one at a time from a file and work out #all possible representations #Read in each number, and translate it to a word/number encoding while ( <NUMFILE> ) { #Remove newline chomp; $read_num =3D $_; $number =3D $_; #Munge number into a purely numerical form(sic) $number =3D~ s/[^[0-9]//og; #Try and find some matches %translations =3D do_translations($number, ""); #Anything? if ( !%translations ) { #No, so use a leading number $number =3D~ s/^([0-9])//o; $translations{$1} =3D $number; } #Work through our hash of things to process/print while ( %translations ) { while ( ($name, $number) =3D each %translations ) { #If the remaining string is empty, then we can print out our = mapping if ( $number eq "" ) { print "$read_num: $name\n"; } else { #Try and match remaining number, passing along how far we've = got #the " " is to separate word/number tokens %temp_hash =3D do_translations($number, $name . " "); #Any matches? if ( !%temp_hash ) { #No, can we try a number if ( $name =3D~ /[^0-9]$/o ) { #Yes $number =3D~ s/^([0-9])//o; $temp_hash{$name . " " . $1} =3D $number; } } #Add what we've got this time through to our #hash of things to process %working_hash =3D (%working_hash, %temp_hash); } } #New hash to process %translations =3D %working_hash; undef %working_hash; } } #Thank you and goodnight close NUMFILE; exit 0; #This function does the mapping #We look for each number in the hash and get all mappings that exist #we then do the same for each that number minus it's last digit and so = on #always storing the matches and what substring they leave sub do_translations($$) { my $num; my $remaining_num =3D ""; my $lead_name; my %translated; #Get the function arguments $num =3D shift; $lead_name =3D shift; #Look for this number and all shorter versions in the hash while ( $num ) { #Do we have any matches? if ( defined $lookup_hash{$num} ) { #Store each match and the remainig digits foreach ( @{$lookup_hash{$num}} ) { $translated{$lead_name . $_} =3D $remaining_num; } } #Lop off the last digit and add it to the remainder $num =3D~ s/([0-9])$//o; $remaining_num =3D $1 . $remaining_num; } return %translated; } __END__ ------=_NextPart_000_001B_01BF3595.41CE46A0-- ==== Want to unsubscribe from Fun With Perl? Well, if you insist... ==== Send email to <fwp-request@technofile.org> with message _body_ ==== unsubscribe