Skip to content

Instantly share code, notes, and snippets.

@RangerDane
Last active September 13, 2018 20:43
Show Gist options
  • Save RangerDane/d6306d136b1736fd0a78e38af634bb00 to your computer and use it in GitHub Desktop.
Save RangerDane/d6306d136b1736fd0a78e38af634bb00 to your computer and use it in GitHub Desktop.
markov chain of varying depth (character level)
# nonsense.rb
# a markov chain of varying depth
# USAGE: make a new nonsense tree, add lines, then chain!
# > non = Nonsense.new 2
# > non.add_line "What is happening"
# > non.add_line "The world is on fire"
# > non.chain
# => "What won hat woren ire worenis hape"
class Nonsense
def initialize( depth = 8 )
@tree = {}
@depth = depth
@loaded = []
end
def add_line( line )
line = line.split("") + [nil]
history = []
line.each do |char|
key = history.join # "", then "W", then "Wh", etc.
ensure_tree key
@tree[key][:freq] += 1
@tree[key][:next][char] ||= 0
@tree[key][:next][char] += 1
history.push char
# history.push char.downcase
history.shift if history.length > @depth
end
true
end
def next( token = "" )
# token = token.downcase
return nil unless @tree[token]
freq = @tree[token][:freq]
freq = 1 if freq == 0
check = rand * freq
pool = 0
@tree[token][:next].each do |char,occ|
pool += occ
return char if check < pool
end
# check > freq = this token terminates the line.
nil
end
def chain( seed = "" )
seed = seed[0...@depth]
char = self.next seed
output = [seed]
history = seed.split("")
while char
output.push char
history.push char
history.shift if history.length > @depth
char = self.next history.join
end
output.join
end
def inspect
"Nonsense chain of depth #{@depth}"
end
private
def ensure_tree( key )
@tree[key] ||= {
freq: 0,
next: {}
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment