# Lojic Technologies

## Solving Anagrams in Ruby

Someone posted a question on comp.lang.ruby recently asking for help with solving anagrams. The poster originally asked about ways of generating permutations and several people pointed him to the facets library which has some permutation utility functions. As it turns out, I benchmarked the following naive permutation generator as 3 times faster than the facets library code:

```def words chars, result='', &b
if chars.empty?
yield result
else
chars.length.times do |i|
c = (x = chars.clone).slice!(i)
words(x, result + c, &b)
end
end
end
```

However, generating all possible combinations of letters in an anagram is a very bad approach which doesn’t take into consideration key knowledge about the problem. Rather than generating all permutations of an anagram, which is infeasible for longer words, we can precompute a hash from our dictionary by using the sorted letters of words as keys. Then to solve an anagram, we simply sort the letters in the anagram and look it up in the hash.

The first program creates the hash and serializes it to disk for future anagram solving:

```words = Hash.new([])

File.open("/usr/share/dict/words", "r") do |file|
while line = file.gets
word = line.chomp
words[word.split('').sort!.join('')] += [word]
end
end

File.open("word_hash", "w") do |file|
Marshal.dump(words, file)
end
```

The second program loads the serialized hash from disk to solve anagrams that we type at the console:

```words = nil

File.open("word_hash", "r") do |file|
end

while true
print "Enter word: "
anagram = gets.chomp
sorted_anagram = anagram.split('').sort!.join('')
p  words[sorted_anagram]
end
```

This is really fast, but there are probably better methods. If you have one, feel free to add a comment with the code.

October 22, 2007 at 7:53 pm

Posted in programming

Tagged with , ,

### 4 Responses

1. Very smart, small and clean code. I would just add .downcase to gets.chomp at line 9. All words in the dictionary are downcase and so you can type in any case and get the same answer. Thanks!

Alejandro Sierra

May 17, 2009 at 9:43 am

2. […] I came across this page, Solving anagrams in Ruby. […]

3. This is a really neat idea! I may use something similar for an iphone app I’m working on…

Thanks!

James

February 14, 2011 at 10:54 pm

4. if (ARGV[0].upcase.split(“”).uniq.sort.join() == ARGV[1].upcase.split(“”).uniq.sort.join())
puts “\n Yes! #{ARGV[0]} and #{ARGV[1]} are anagrams.”
else
puts “\n No. they’re not anagrams.”
end

uncleric

August 25, 2014 at 2:17 am