Skip to content

Instantly share code, notes, and snippets.

@F-3r
Created November 20, 2019 13:13
Show Gist options
  • Save F-3r/0b882ec57cdfc14604c1453ac0eb7fb4 to your computer and use it in GitHub Desktop.
Save F-3r/0b882ec57cdfc14604c1453ac0eb7fb4 to your computer and use it in GitHub Desktop.
Markov chain implementation for the arlt.rb bot
class Markov
PHRASE_SEPARATOR = /[\.;]/
WORD_SEPARATOR = " "
attr_reader :knowledge, :order
def initialize(order: 2)
@knowledge = {}
@order = order
end
def read(text)
phrases(text).each do |phrase|
(Array.new(order, " ") + words(phrase)).each_cons(order + 1) { |*key, value | learn key, value }
end
knowledge
end
def compose()
generate(Array.new(order, " ")).drop(order).join(" ") << "."
end
def generate(chain)
key = chain.last(order).join(" ")
alternatives = knowledge[key]
following = alternatives ? alternatives.sample : nil
while following
chain << following
key = chain.last(order).join(" ")
alternatives = knowledge[key]
following = alternatives ? alternatives.sample : nil
end
chain
end
def learn(a, b)
key = a.join(" ")
knowledge[key] ||= []
knowledge[key] << b
end
def words(text, sep: WORD_SEPARATOR)
text.split(sep).reject(&:empty?)
end
def phrases(text, sep: PHRASE_SEPARATOR)
text.split(sep).reject(&:empty?).each(&:strip!)
end
def store(file = "markov-#{order}.db")
File.write file, Marshal.dump(knowledge)
self
end
def load(file = "markov-#{order}.db")
@knowledge = Marshal.load File.read file
self
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment