Skip to content

Instantly share code, notes, and snippets.

@kuczmama
Last active May 16, 2019 03:23
Show Gist options
  • Select an option

  • Save kuczmama/186f785ef67042e4edd2152389106ddd to your computer and use it in GitHub Desktop.

Select an option

Save kuczmama/186f785ef67042e4edd2152389106ddd to your computer and use it in GitHub Desktop.
n level markov chain to randomly generate text
class String
def blank?
self.nil? || self.empty?
end
def present?
!self.blank?
end
end
class Array
def blank?
self.nil? || self.empty?
end
def present?
!self.blank?
end
end
class NilClass
def blank?
self.nil? || self.empty?
end
def present?
!self.blank?
end
end
class MarkovChain
attr_accessor :memory_1, :memory_2, :memory_3
def initialize
@memory_1 = {}
@memory_2 = {}
@memory_3 = {}
end
def train(path: )
tokens = File.read(path).split(" ")
(0...tokens.length - 3).each do |i|
one_key = tokens[i]
one_value = tokens[i + 1]
two_key = [one_key, one_value]
two_value = tokens[i + 2]
three_key = [one_key, one_value, two_value]
three_value = tokens[i + 3]
next if one_key.blank? || one_value.blank? || two_value.blank? || three_key.blank? || three_value.blank?
@memory_1[one_key] = [] if @memory_1[one_key].blank?
@memory_2[two_key] = [] if @memory_2[two_key].blank?
@memory_3[three_key] = [] if @memory_3[three_key].blank?
@memory_1[one_key] << one_value
@memory_2[two_key] << two_value
@memory_3[three_key] << three_value
end
end
def level_0
result = @memory_1.keys.sample
# puts "level 0: #{result}"
result
end
def level_1(curr_state)
return nil unless curr_state.present?
curr_state = curr_state.first if curr_state.is_a?(Array) && curr_state.length == 1
values = @memory_1[curr_state]
return nil if values.blank?
result = values.sample
# puts "level 1: #{result}"
result
end
def level_2(curr_state)
return nil unless curr_state.present?
return nil unless curr_state.is_a?(Array)
return nil unless curr_state.length == 2
values = @memory_2[curr_state]
return nil if values.blank?
result = values.sample
# puts "Level 2: #{result}"
result
end
def level_3(curr_state)
return nil unless curr_state.present?
return nil unless curr_state.is_a?(Array)
return nil unless curr_state.length == 3
values = @memory_3[curr_state]
return nil if values.blank?
result = values.sample
# puts "Level 3: #{result}"
result
end
def next_word(curr_state="")
level_1_key = curr_state.is_a?(Array) ? curr_state.last : curr_state
level_2_key = (curr_state.is_a?(Array) && curr_state.length >= 2) ? curr_state[-2..-1] : curr_state
level_3(curr_state) || level_2(level_2_key) || level_1(level_1_key) || level_0
end
end
def give_speech(markov_chain, length=100)
result = ""
last_word = markov_chain.level_0
result += markov_chain.level_1(last_word) + " " + last_word
(0..length).each do |i|
last_word = markov_chain.next_word(result.split(" ")[-3..-1])
result += " " + last_word
end
result
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment