------extPart_000_0135_01C518EF.C6101400
Content-Type: text/plain;
	charsetS-ASCII"
Content-Transfer-Encoding: 7bit

Attached is my solution.

Enjoy 

-----Original Message-----
From: Ruby Quiz [mailto:james / grayproductions.net] 
Sent: Friday, February 18, 2005 6:58 AM
To: ruby-talk ML
Subject: [QUIZ] 1-800-THE-QUIZ (#20)

The three rules of Ruby Quiz:

1.  Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2.  Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3.  Enjoy!

--------------------

Many companies like to list their phone numbers using the letters printed on most telephones.  This makes the number easier to
remember for customers.  A famous example being 1-800-PICK-UPS.

This week's quiz is to write a program that will show a user possible matches for a list of provided phone numbers.

Your script should behave as a standard Unix filter, reading from files specified as command-line arguments or STDIN when no files
are given.  Each line of these files will contain a single phone number.

For each phone number read, your filter should output all possible word replacements from a dictionary.  Your script should try to
replace every digit of the provided phone number with a letter from a dictionary word; however, if no match can be made, a single
digit can be left as is at that point.  No two consecutive digits can remain unchanged and the program should skip over a number
(producing no output) if a match cannot be made.

Your script should allow the user to set a dictionary with the -d command-line option, but it's fine to use a reasonable default for
your system.  The dictionary is expected to have one word per line.

All punctuation and whitespace should be ignored in both phone numbers and the dictionary file.  The program should not be case
sensative, letting "a" "A". 
Output should be capital letters and digits separated at word boundaries with a single dash (-), one possible word encoding per
line.  For example, if your program is fed the number:

	873.7829

One possible line of output is

	USE-RUBY

According to my dictionary.

The number encoding on my phone is:

	2   B C
	3   E F
	4   H I
	5   K L
	6   N O
	7   Q R S
	8   U V
	9   X Y Z

Feel free to use that, or the encoding on your own phone.

------extPart_000_0135_01C518EF.C6101400
Content-Type: application/octet-stream;
	namehonewords.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filenamehonewords.rb"

#!/usr/bin/env ruby
require 'set'
require 'optparse'

dict  il

ARGV.options do |opts|
  opts.banner  Usage: ruby #{__FILE__} [options] [input files]"
  opts.on('Options:')
  opts.on('--dictionary DICTFILE', '-d', 'Specify dictionary file') { |file|
    File.open(file) { |f| dict  .readlines }
  }
  opts.on("--help", "-h", "This text") { puts opts; exit 0 }
  
  opts.parse!
end

l2n  }
%w{ABC DEF GHI JKL MNO PQRS TUV WXYZ}.each_with_index { |letters, num|
  letters.scan(/./).each { |c|
    l2n[c]  #{num + 2}"
  }
}

dict  w{use ruby a quick brown fox jumped over the lazy laz laxx dog lazyfox f azyfox} unless dict

num_dict  }
dict.each { |word|
  num_word  '
  upword  ord.upcase
  upword.scan(/./).each { |c|
    num_word << l2n[c]
  }
  (num_dict[num_word] || ]) << upword
}

def build_word_list(position_list, phnumber, words  et.new, word  ')
  position  ord.length - word.count('-')
  if position > osition_list.size
    word.chop! while word[-1, 1] '-'
    words << word
    return
  end
  position_list[position].each { |word_ary|
    next unless word_ary
    word_ary.each { |w|
      new_word  ord.empty? ? "#{w}" : "#{word}-#{w}"
      build_word_list(position_list, phnumber, words, new_word)
      build_word_list(position_list, phnumber, words, "#{new_word}-#{phnumber[position + w.length, 1]}")
    }
  }
  words
end

while phone  ets
  next if phone.gsub!(/[^\d]/, '').empty?
  digits  hone.scan(/./)
  position_list  rray.new(digits.size)
  digits.each_with_index { |d, i|
    length_list  osition_list[i]  rray.new(digits.size - i)
    num_word  '
    (i...digits.size).each { |j|
      num_word << digits[j]
      length_list[j - i]  um_dict[num_word]
    }
  }
  
  build_word_list(position_list, phone, build_word_list(position_list, phone), phone[0,1]).each { |w|
    puts w
  }
end

------extPart_000_0135_01C518EF.C6101400--