"James Edward Gray II" <james / grayproductions.net> wrote:
> On Feb 24, 2005, at 7:25 PM, Dave Burt wrote:
>
>> Yes, I'm a Usenetter, and the gateway did have a little nap back there
>> (though it seems happy now, as you read my last message). Not your fault.
>
> Dave, would you please resend your message so it will show up on the 
> mailing list for those of us who missed it?  Thanks.
>

OK. Apologies to c.l.r for the re-post. Google groups link:
http://groups-beta.google.com/group/comp.lang.ruby/browse_thread/thread/90246bd3ecdf05cc/53f008423008c2fb?#53f008423008c2fb

Originally posted:  Wed, 23 Feb 2005 12:41:42 GMT
Subject: Re: [SOLUTION] [QUIZ] 1-800-THE-QUIZ (#20)

"Brian Schröäer" <ruby / brian-schroeder.de> wrote:
> i once again found the time to do the ruby quiz. I liked the quiz
> because it was short, and on the other hand harder than I thought.

Me too.

> I
> skipped the part about skipping letters in my first try, and when I had
> to add it it made me think quite a bit. (I first skipped letters instead
> of numbers, because I got confused in my datastructure.)

I tackled it in bits, too, roughly corresponding to my 3 main functions:
match, combine and new_phone_numbers. (See the end of this message for a
link to the program.)

Step 0: setup
Get a map get a digit corresponding to any character. {'A'=>'2',
'B'=>'2'...}
Read dictionary into a hash mapping digit-strings to an array of the words
they can make (uppercase).
{'228' => ['BAT', 'CAT'], ...}

Step 1: match
Check every possible substring of the number for matches in the dictionary
map. (Initially, I just printed these underneath the string in the
corresponding position. I thought I was nearly there.) To move on, I got
this function to produce an array of all these matches, each match being
represented like this: {:start => 1, :length => 3, :words => ['BAT', 'CAT']}

Step 2: combine
Combine gets all non-overlapping combinations of matches from the above
step, and returns an array of combinations. Each combination is an array of
matches (see above... I really should have made Match a class, hey?).

Step 3: new_phone_numbers
Iterates through each word in each match in each combination... except it's
not that simple. 3 combinations x 3 matches each x 1 word each = 9
solutions, no worries. 3 combinations x 3 matches each x 3 words each = 243
solutions. Each word in each match has to be shown with every word in every
other match in the combination. Enter an array of indexes - an index for
each match to keep track of which word it's up to (the variable's called
"index"). So the array of indexes starts at each match's last word, and gets
decremented until it's [0,0...].
Now we've got that tricky loop sorted out, the easy part: substitute the
current word (using index) from each match into the number, and finally
reject the number if it's got 2 digits in a row.

And here's the final product.
http://www.dave.burt.id.au/ruby/phone_words.rb

Cheers,
Dave