Index and Query (#54)

I’m a little late to the party. I just finished PickAxe2 and this is
my first quiz (or Ruby program.) Mine doesn’t Marshal the data, but
does offer both has_any and has_all methods.

class Lexicon

@@word_index = {}
@@i = -1

def initialize()
@map = Hash.new(0)
end

def add(doc,word)
@@word_index[word] = @@i+=1 unless @@word_index.key?(word)
@map[doc] |= bitmask(word)
end

def has_any(*words)
@map.keys.select {|k| (@map[k] & bitmask(words)) > 0 }
end

def has_all(*words)
return [] if words.detect { |word| !@@word_index.key?(word) }
x = bitmask(words)
@map.keys.select {|k| (@map[k] & x) == x }
end

private

def bitmask(words)
x = 0
words.each {|word| x |= 1 << @@word_index[word] if
@@word_index.key?(word)}
x
end

end

index = Lexicon.new
ARGF.each do |line|
line.downcase.split.each { |word| index.add($FILENAME,word) }
end

while words = $stdin.gets
puts index.has_all(*words.split).join(’ ')
end