Here's my solution. It doesn't really have any clever optimizations,
but it runs in seconds.
James Edward Gray II
#!/usr/bin/env ruby
unless ARGV.size >= 2 and ARGV[1] =~ /^[1-9]|1\d|2[0-6]$/
puts "Usage: #$0 WORD_LIST_FILE(S) MINIMUM_STEM_LIMIT"
exit
end
$limit = ARGV.pop.to_i
$stems = { }
while line = ARGF.gets
line.chomp!
line.tr!("^a-zA-Z", "")
line.downcase!
next unless line.length == 7
word = line.split("")
word.each_index do |i|
stem = word.dup
stem.delete_at(i)
stem = stem.sort.join
if $stems.include?(stem)
$stems[stem] << word[i] unless $stems[stem].include?(word[i])
else
$stems[stem] = [ word[i] ]
end
end
end
$stems.each_pair do |stem, letters|
next if letters.size < $limit
puts stem
puts "\t#{letters.size}: #{letters.sort.join}"
end