Execute a Markov algorithm: Difference between revisions
Content added Content deleted
Not a robot (talk | contribs) (Add CLU) |
|||
Line 2,786: | Line 2,786: | ||
11111111111111111111 |
11111111111111111111 |
||
00011H1111000</pre> |
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}}== |
=={{header|Julia}}== |