# Finding Semordnilaps

My wife recently developed an interest in semordnilaps, so I thought I would take a stab at writing a script that will find some. What I came up with finds a subset of all two word to two word semordnilaps. Generally you don’t consider whitespace and punctuation in palindromes and semordnilaps, so this code doesn’t either.

It turns out that filtering out proper names vastly reduces the number of semordnilaps found, and I didn’t really appreciate the ones which contained proper names anyway, so I took those out.

```words = {}
File.open("/usr/share/dict/words") do |file|
file.each do |line|
if line.length > 4 # don't accept one or two letter words.
word = line.strip
next if word.downcase != word # proper names have capitals, exclude those.
words[word.downcase.gsub(/[^a-z]/, '')] = true
end
end
end

words.each do |word1, k|
p_words = {}
word_finds = 0

word1 = word1.reverse
first_words = []
# skip words that when reversed don't match the ending of another word.
(1 .. (word1.length - 1)).each do |i|
if words[word1[0..i]]
first_words << word1[0..i]
end
end
if first_words.count == 0
next
end

words.each do |word2, k|
two_words = word1 + word2.reverse
(2 .. two_words.length).each do |i|
if words[two_words[0..(i - 1)]] && words[two_words[i..(two_words.length-1)]]
p_words[two_words[0..(i - 1)] + ' ' + two_words[i..(two_words.length-1)]] = word2 + ' ' + word1.reverse
word_finds += 1
end
end
end
if word_finds > 0
puts p_words
end
end

```

And this gives you some great semordnilaps like:

• cite catnip”=>”pint acetic”
• “stub aloof”=>”fool abuts”
• “tubas gals”=>”slags abut”
• “sane railed”=>”deli arenas”
• “reis trailed”=>”deli artsier”
• “diva lived”=>”devil avid”
• “stabs faced”=>”decafs bats”

All told, I got a 2.7MB text file. I am sure that there are better ones in there.