[QUIZ][SOLUTION] 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