Skip to content

Instantly share code, notes, and snippets.

@mrkn
Last active December 28, 2016 06:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrkn/98f35a7e56a08a417a9d4a0e2dd0378f to your computer and use it in GitHub Desktop.
Save mrkn/98f35a7e56a08a417a9d4a0e2dd0378f to your computer and use it in GitHub Desktop.
class Vocabulary
def initialize
@words = []
@index = {}
end
def <<(word)
unless @index[word]
@index[word] = @words.length
@words << word
end
self
end
def index(word)
@index[word]
end
def each_with_index(&block)
@words.each_with_index &block
end
end
class Document
def initialize(vocabulary, initial_bitmap=0)
@vocabulary = vocabulary
@bitmap = initial_bitmap
end
attr_reader :vocabulary
attr_reader :bitmap
def index(word)
@vocabulary.index(word)
end
def <<(word)
unless (i = index(word))
@vocabulary << word
i = index(word)
end
@bitmap |= 1 << i
self
end
def &(document)
check_compatibility(document)
self.class.new(vocabulary, @bitmap & document.bitmap)
end
def |(document)
check_compatibility(document)
self.class.new(vocabulary, @bitmap | document.bitmap)
end
def ^(document)
check_compatibility(document)
self.class.new(vocabulary, @bitmap ^ document.bitmap)
end
def to_a
[].tap do |ary|
n = bitmap
vocabulary.each_with_index do |word, index|
ary << word if n & 1 > 0
n >>= 1
end
end
end
private
def check_compatibility(document)
return if @vocabulary == document.vocabulary
raise 'Incompatible document'
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment