--
lternative 004B40AD8525714C_Content-Type: text/plain; charset="US-ASCII"
# Author: Shane Emmons
#
# Quiz 74: Markov Chains
#
# This is based off of the classic Mark V. Shaney program. The
# basic algorithm only looked at the previous two words. I have
# changed it, so that it can check the previous four, previous three,
# previous two, or the previous word(s) to find the next reasonable
# choice. I also added some smarter end of phrase checks along with
# the standard rubifying.
#
# I was thinking, but have not tried, what would happen if you
# sent source code through the algorithm? Obviously some things
# would need to be changed for "phrase_breaks", but I wonder if
# anything would actually sucessfully run.
class MarkovChain
attr_reader :phrase_breaks, :phrases
def initialize( book )
@book ook
@phrases rray.new( 4 ).fill( Hash.new )
@phrase_breaks rray.new
end
def read( book book )
prev '', '', '', '' ]
words ile.open( book ).read.split
words.each do |word|
word.gsub!( /"/, '' )
unless prev[ 0 ].eql?( '' )
@phrases.each_index do |i|
prev_words rev[ 0 .. i ].join( ' ' )
@phrases[ i ][ prev_words ] rray.new unless
@phrases[ i ].has_key?( prev_words )
@phrases[ i ][ prev_words ] << word.downcase
@phrase_breaks << prev_words if prev_words.match(
/[.!?]$/ )
end
end
prev.pop and prev.insert( 0, word )
end
end
def get_chain( num_want )
chain rray.new
num_made
prev '', '', '', '' ]
prevs rray.new( 4 )
prev.each_index { |i| prevs[ i ] rev[ 0 .. i ].join( ' ' ) }
while num_made < num_want do
until @phrases[ 3 ].has_key?( prevs[ 3 ] ) or
@phrases[ 2 ].has_key?( prevs[ 2 ] ) or
@phrases[ 1 ].has_key?( prevs[ 1 ] ) or
@phrases[ 0 ].has_key?( prevs[ 0 ] )
prev phrase_breaks[ rand( @phrase_breaks.length )
].split
prev.each_index { |i| prevs[ i ] rev[ 0 .. i ].join( '
' ) }
end
words rray.new
@phrases.each_index do |i|
prev_words rev[ 0 .. i ].join( ' ' )
words phrases[ i ][ prev_words ] if
@phrases[ i ].has_key?( prev_words )
end
word ords[ rand( words.length ) ]
chain << word
prev.shift and prev.push( word )
prev.each_index { |i| prevs[ i ] rev[ 0 .. i ].join( ' ' )
}
num_made + if prev[ -1 ].match( /[.!?]$/ )
end
chain
end
end
mChain arkovChain.new( ARGV[ 0 ] )
mChain.read
print mChain.get_chain.join( ' ' ), "\n"
--
lternative 004B40AD8525714C_