Class: Markov::Chain

Inherits:
Object
  • Object
show all
Includes:
Statistics
Defined in:
lib/markov/chain.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name: 'anonymous', order: 2, new_words: false) ⇒ Chain

Returns a new instance of Chain.



9
10
11
12
13
14
15
16
17
18
# File 'lib/markov/chain.rb', line 9

def initialize(name: 'anonymous', order: 2, new_words: false)
  @name = name
  @order = order
  @words = []
  @new_words = new_words

  @transition_matrices = 1.upto(order+1).map do |depth|
    TransitionMatrix.new(depth: depth)
  end
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



5
6
7
# File 'lib/markov/chain.rb', line 5

def name
  @name
end

#new_wordsObject (readonly)

Returns the value of attribute new_words.



6
7
8
# File 'lib/markov/chain.rb', line 6

def new_words
  @new_words
end

#orderObject (readonly)

Returns the value of attribute order.



6
7
8
# File 'lib/markov/chain.rb', line 6

def order
  @order
end

#transition_matricesObject (readonly)

Returns the value of attribute transition_matrices.



7
8
9
# File 'lib/markov/chain.rb', line 7

def transition_matrices
  @transition_matrices
end

#wordsObject (readonly)

Returns the value of attribute words.



6
7
8
# File 'lib/markov/chain.rb', line 6

def words
  @words
end

Instance Method Details

#count_syllables(s) ⇒ Object



20
21
22
# File 'lib/markov/chain.rb', line 20

def count_syllables(s)
  s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size
end

#generate!(max: 1_000, start_text: "", show: false) ⇒ Object

, original: true)



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/markov/chain.rb', line 69

def generate!(max: 1_000, start_text: "", show: false) #, original: true)
  generated_count = 0
  generated_text = start_text.chars
  word = nil

  until max && (generated_count +=1)>=max
    word = generate_word!(context: new_words ? ["\n"] : generated_text)

    if show
      word.chars.each do |ch|
        sleep 0.05 + rand*(0.01)
        yield ch
      end
    end

    generated_count += word.chars.count
    generated_text += word.chars
  end

  generated_text.join
end

#generate_word!(context: ["\n"]) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/markov/chain.rb', line 91

def generate_word!(context: ["\n"])
  if new_words
    word = @words.first
    until !@words.include?(word.chomp) && word.chomp.match(/^[A-Z][a-z]+$/)
      word = (generate_any_word!) #.chomp #(context: generated_text)
    end
    @words.push(word.chomp)
    word
  else
    generate_any_word!(context: context) #generated_text)
  end    
end

#parse(text) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/markov/chain.rb', line 42

def parse(text)
  puts "---> PARSE TEXT!"
  puts "     Analyzing character distribution..."
  text.gsub!(/[^A-Za-z \n]/, '')
  @transition_matrices.each do |matrix|
    cons_chars = text.chars.each_cons(matrix.depth)
    progress_bar = ProgressBar.create(
      title: "Parsing characters (depth #{matrix.depth})",
      total: cons_chars.count
    )
    cons_chars.each do |word_group|
      matrix.add_transition(word_group)
      progress_bar.increment
  end
  end

  puts "     Analyzing prosody..."
  @words = text.gsub(/[^A-Za-z \n]/,'').split(/[\n ]/).map(&:strip)
  puts "---> done!"
end

#predict_next_state(last_states) ⇒ Object



63
64
65
66
67
# File 'lib/markov/chain.rb', line 63

def predict_next_state(last_states)
  transition_probabilities = transitions_from(last_states)
  next_state = RandomEvent.new(transition_probabilities)
  next_state.predict!
end

#transitions_from(states, primary: true) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/markov/chain.rb', line 24

def transitions_from(states, primary: true)
  states = [states] unless states.is_a?(Array)

  matrices = @transition_matrices.reverse

  candidate_matrix = matrices.
    select { |m| states.count >= m.depth - 1 }.
    detect do |matrix|
      matrix.transitions_from(states)
    end

  if candidate_matrix
    candidate_matrix.transitions_from(states)
  else
    {}
  end
end