Execute a Markov algorithm: Difference between revisions

(Add CLU)
Line 2,786:
11111111111111111111
00011H1111000</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
This entry assumes that the rule sets are in a single file (markov_rules.txt);
that the rule sets are separated by a blank line;
and that the corresponding test cases are in a separate file (markov_tests.txt), with one test case per line.
In addition, for simplicity, only blanks are counted as <whitespace>.
 
With the following program, jq could then be invoked as follows:
<pre>
jq -nrR --rawfile markov_rules markov_rules.txt -f program.jq markov_tests.txt
</pre>
 
'''Preliminaries'''
<lang jq># Output: the input string with all its regex-special characters suitably escaped
def deregex:
reduce ("\\\\", "\\*", "\\^", "\\?", "\\+", "\\.", "\\!", "\\{", "\\}", "\\[", "\\]", "\\$", "\\|",
"\\(", "\\)" ) as $c
(.; gsub( $c; $c));
 
# line-break
def lb: "\n";
 
def split2($s):
index($s) as $ix
| if $ix then [ .[:$ix], .[$ix + ($s|length):]] else null end;
 
def trim: sub("^ *";"") | sub(" *$";"");
 
# rulesets are assumed to be separated by a blank line
# input: a string
def readRules:
trim | split("\(lb)\(lb)") | map(split(lb)) ;
 
# tests are assumed to be on consecutive lines via `inputs`
# Output: an array
def readTests: [inputs | trim | select(length>0) ];
 
def rules: $markov_rules | readRules;
 
def tests: readTests;</lang>
 
<lang jq>def parseRules($rules):
"^ *(?<period>[.]?) *(?<rule>.*)" as $pattern
| reduce $rules[] as $rule ([];
if $rule | (startswith("#") or (test(" -> ")|not)) then .
else ($rule|split2(" -> ")) as $splits
| ($splits[1] | capture($pattern)) as $re
| . + [[($splits[0]|trim|deregex), $re.period, ($re.rule | trim)]]
end );
 
# Input and output: a string
# $rules should be the array-of-triples form of the applicable rules
def chain( $rules ):
{stop: false, string: .}
| until(.stop;
.string as $copy
| .redo = false
| label $out
| foreach ($rules[], null) as $c (.;
if $c == null then .
else .string |= sub($c[0]; $c[2])
| if $c[1] == "."
then ., break $out
elif .string != $copy
then .redo = true
| ., break $out
else .
end
end;
if .redo or $c[1] == "." or $c == null then . else empty end)
| if .redo then . else .stop = true end)
| .string;
 
def proceed:
rules as $rules
| tests as $tests
| range(0; $tests|length) as $ix
| $tests[$ix] as $test
| parseRules( $rules[$ix] ) as $parsed
| $test | chain($parsed)
| " \($test)\n=>\(.)\n" ;
 
proceed</lang>
 
{{out}}
<pre>
I bought a B of As from T S.
=>I bought a bag of apples from my brother.
 
I bought a B of As from T S.
=>I bought a bag of apples from T shop.
 
I bought a B of As W my Bgage from T S.
=>I bought a bag of apples with my money from T shop.
 
_1111*11111_
=>11111111111111111111
 
000000A000000
=>00011H1111000
</pre>
 
 
=={{header|Julia}}==
2,442

edits