Class: RubyMarkovify::Chain

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_markovify/chain.rb

Instance Method Summary collapse

Constructor Details

#initialize(corpus, state_size, model = nil) ⇒ Chain

Returns a new instance of Chain.



8
9
10
11
# File 'lib/ruby_markovify/chain.rb', line 8

def initialize(corpus, state_size, model = nil)
  @state_size = state_size
  @model = model || build(corpus, @state_size)
end

Instance Method Details

#build(corpus, state_size) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/ruby_markovify/chain.rb', line 13

def build(corpus, state_size)
  fail ArgumentError, '`corpus` must be an Array of Arrays!' unless corpus.is_a?(Array) && corpus[0].is_a?(Array)

  model = {}

  corpus.each do |run|
    items = [:begin] * state_size + run + [:end]

    0.upto(run.length + 1) do |i|
      state = items[i...i+state_size]
      follow = items[i+state_size]

      model[state] ||= {}
      model[state][follow] ||= 0
      model[state][follow] += 1
    end
  end

  model
end

#gen(init_state = nil) ⇒ Object Also known as: walk



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/ruby_markovify/chain.rb', line 41

def gen(init_state = nil)
  state = init_state || [:begin] * @state_size
  result = []
  loop do
    next_word = move(state)
    break if next_word == :end
    result << next_word
    state = state[1..-1] + [next_word]
  end
  result
end

#move(state) ⇒ Object



34
35
36
37
38
39
# File 'lib/ruby_markovify/chain.rb', line 34

def move(state)
  choices, weights = @model[state].keys, @model[state].values
  cumdist = RubyMarkovify.cumulative_sum(weights)
  r = rand * cumdist[-1]
  choices[cumdist.index { |e| e >= r }]
end