Execute a Markov algorithm: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
Line 11: Line 11:
<lang Ruby>raise "Please input an input code file, an input data file, and an output file." if ARGV.size < 3
<lang Ruby>raise "Please input an input code file, an input data file, and an output file." if ARGV.size < 3


rules = File.readlines(ARGV[0]).map do |line|
rules = File.readlines(ARGV[0]).inject([]) do |rules, line|
if line =~ /^\s*#/
if line =~ /^\s*#/
nil
rules
elsif line =~ /^(.+)\s+->\s+(\.?)(.*)$/
elsif line =~ /^(.+)\s+->\s+(\.?)(.*)$/
[$1, $3, $2 != ""]
rules << [$1, $3, $2 != ""]
else
else
raise "Syntax error: #{line}"
raise "Syntax error: #{line}"
end
end
end.compact
end


File.open(ARGV[2], "w") do |file|
File.open(ARGV[2], "w") do |file|
file.write(File.read(ARGV[1]).tap { |input_data|
file.write(File.read(ARGV[1]).tap { |input_data|
while rules.find { |match, replace, term|
while (matched = rules.find { |match, replace, term|
if input_data[match]
input_data[match] and input_data.sub!(match, replace)
}) and !matched[2]
input_data.sub!(match, replace)
break if term
true
else
false
end
}
end
end
})
})

Revision as of 07:26, 15 December 2009

This page uses content from Wikipedia. The original article was at Markov_algorithm. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)
Task
Execute a Markov algorithm
You are encouraged to solve this task according to the task description, using any language you may know.

Create an interpreter for a Markov Algorithm. Rules have the syntax:

<comment> ::= # {<any character>} <rule> ::= <pattern> <whitespace> -> <whitespace> [.] <replacement>
<whitespace> ::= (<tab> | <space>) [<whitespace>]
There is one rule per line. If there is a . present before the <replacement>, then this is a terminating rule in which case the interpreter must halt execution.

Ruby

Works with: Ruby version 1.8.7

<lang Ruby>raise "Please input an input code file, an input data file, and an output file." if ARGV.size < 3

rules = File.readlines(ARGV[0]).inject([]) do |rules, line|

 if line =~ /^\s*#/
   rules
 elsif line =~ /^(.+)\s+->\s+(\.?)(.*)$/
   rules << [$1, $3, $2 != ""]
 else
   raise "Syntax error: #{line}"
 end

end

File.open(ARGV[2], "w") do |file|

 file.write(File.read(ARGV[1]).tap { |input_data|
   while (matched = rules.find { |match, replace, term|
     input_data[match] and input_data.sub!(match, replace)
   }) and !matched[2]
   end
 })

end</lang>