I recently came across an old programming language challenge while I was looking for the new D programming language (http://www.digitalmars.com/d/lisp-java-d.html). The challenge is to write a program which will output all possible combinations of phone numbers with words (like 555-ruby) given a dictionnary and a phone number in input. Lionello Lunesu took 1h15 and 55 lines of D code to achieve the goal. With the links on his site, I then look at this site and this one from Peter Norvig, a Lisp programmer, which took 2h and 45 lines of lisp code to do it. Being a Ruby fan, I tried to solve this challenge with one of my favorite language: Ruby. I was telling everybody how much of a productivity boost I got since I learned this new language, I thought it was time to prove it. And guess what, I was able to achieve it with pretty good results: 20 lines of Ruby code in 50 minutes (not couting blanks and comments like everybody else)! Here is my code:
# Number/letters mapping
map = {'2'=>'a'..'c', '3'=>'d'..'f', '4'=>'g'..'i', '5'=>'j'..'l', '6'=>'m'..'o',
'7'=>'p'..'s', '8'=>'t'..'v', '9'=>'w'..'z', '0'=>[], '1'=>[]}
if ARGV.length != 2
puts 'Usage: {dictFile} {phoneNumber}'
else
# Reading the file in memory (*nix or Windows (or Mac???))
f = IO.popen("cat #{ARGV[0]}") rescue IO.popen("type #{ARGV[0]}") rescue fail '?'
content = f.readlines
# For each word found
content.each do |word|
word.chomp!.downcase!
next if word.empty? or word.size != ARGV[1].size # If the word is not good.
good_word = true
ARGV[1].size.times do |i|
# Comparing each letters
if not map[ARGV[1][i,1]].include?(word[i,1])
good_word = false
break
end
end
# Write it if it's good.
puts word if good_word
end
end
That's it! I took a dictionnary from OpenOffice to test my code and it seems to work fine. I know that I could optimize my code, but that's not the point of the challenge. The same thing can be achieved with different languages (Python for instance), but I wanted to share my solution for those of you who are looking at Ruby.
Thursday, April 19, 2007
Subscribe to:
Posts (Atom)