Feat: add new Markdown parser (#39800)
and change all the challenges to new `md` format.
This commit is contained in:
committed by
GitHub
parent
a07f84c8ec
commit
0bd52f8bd1
@ -1,29 +1,36 @@
|
||||
---
|
||||
title: Execute a Markov algorithm
|
||||
id: 59e09e6d412c5939baa02d16
|
||||
title: Execute a Markov algorithm
|
||||
challengeType: 5
|
||||
forumTopicId: 302260
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Create an interpreter for a <a href="https://en.wikipedia.org/wiki/Markov algorithm" title="wp: Markov algorithm" target="_blank">Markov Algorithm</a>.
|
||||
# --description--
|
||||
|
||||
Create an interpreter for a [Markov Algorithm](<https://en.wikipedia.org/wiki/Markov algorithm> "wp: Markov algorithm").
|
||||
|
||||
Rules have the syntax:
|
||||
<pre>
|
||||
[ruleset] ::= (([comment] | [rule]) [newline]+)*
|
||||
|
||||
<pre>[ruleset] ::= (([comment] | [rule]) [newline]+)*
|
||||
[comment] ::= # {[any character]}
|
||||
[rule] ::= [pattern] [whitespace] -> [whitespace] [.] [replacement]
|
||||
[whitespace] ::= ([tab] | [space]) [[whitespace]]
|
||||
</pre>
|
||||
|
||||
There is one rule per line.
|
||||
If there is a <code>.</code> (period) present before the [replacement], then this is a terminating rule in which case the interpreter must halt execution.
|
||||
|
||||
If there is a `.` (period) present before the \[replacement], then this is a terminating rule in which case the interpreter must halt execution.
|
||||
|
||||
A ruleset consists of a sequence of rules, with optional comments.
|
||||
<span style="font-size: 1.5rem">Rulesets</span>
|
||||
|
||||
Rulesets
|
||||
|
||||
Use the following tests on entries:
|
||||
<strong>Ruleset 1:</strong>
|
||||
<pre>
|
||||
# This rules file is extracted from Wikipedia:
|
||||
# http://en.wikipedia.org/wiki/Markov_Algorithm
|
||||
|
||||
**Ruleset 1:**
|
||||
|
||||
<pre># This rules file is extracted from Wikipedia:
|
||||
# <code>http://en.wikipedia.org/wiki/Markov_Algorithm</code>
|
||||
A -> apple
|
||||
B -> bag
|
||||
S -> shop
|
||||
@ -31,14 +38,20 @@ T -> the
|
||||
the shop -> my brother
|
||||
a never used -> .terminating rule
|
||||
</pre>
|
||||
|
||||
Sample text of:
|
||||
<code>I bought a B of As from T S.</code>
|
||||
|
||||
`I bought a B of As from T S.`
|
||||
|
||||
Should generate the output:
|
||||
<code>I bought a bag of apples from my brother.</code>
|
||||
<strong>Ruleset 2:</strong>
|
||||
|
||||
`I bought a bag of apples from my brother.`
|
||||
|
||||
**Ruleset 2:**
|
||||
|
||||
A test of the terminating rule
|
||||
<pre>
|
||||
# Slightly modified from the rules on Wikipedia
|
||||
|
||||
<pre># Slightly modified from the rules on Wikipedia
|
||||
A -> apple
|
||||
B -> bag
|
||||
S -> .shop
|
||||
@ -46,14 +59,20 @@ T -> the
|
||||
the shop -> my brother
|
||||
a never used -> .terminating rule
|
||||
</pre>
|
||||
|
||||
Sample text of:
|
||||
<code>I bought a B of As from T S.</code>
|
||||
|
||||
`I bought a B of As from T S.`
|
||||
|
||||
Should generate:
|
||||
<code>I bought a bag of apples from T shop.</code>
|
||||
<strong>Ruleset 3:</strong>
|
||||
|
||||
`I bought a bag of apples from T shop.`
|
||||
|
||||
**Ruleset 3:**
|
||||
|
||||
This tests for correct substitution order and may trap simple regexp based replacement routines if special regexp characters are not escaped.
|
||||
<pre>
|
||||
# BNF Syntax testing rules
|
||||
|
||||
<pre># BNF Syntax testing rules
|
||||
A -> apple
|
||||
WWWW -> with
|
||||
Bgage -> ->.*
|
||||
@ -65,14 +84,20 @@ T -> the
|
||||
the shop -> my brother
|
||||
a never used -> .terminating rule
|
||||
</pre>
|
||||
|
||||
Sample text of:
|
||||
<code>I bought a B of As W my Bgage from T S.</code>
|
||||
|
||||
`I bought a B of As W my Bgage from T S.`
|
||||
|
||||
Should generate:
|
||||
<code>I bought a bag of apples with my money from T shop.</code>
|
||||
<strong>Ruleset 4:</strong>
|
||||
This tests for correct order of scanning of rules, and may trap replacement routines that scan in the wrong order. It implements a general unary multiplication engine. (Note that the input expression must be placed within underscores in this implementation.)
|
||||
<pre>
|
||||
### Unary Multiplication Engine, for testing Markov Algorithm implementations
|
||||
|
||||
`I bought a bag of apples with my money from T shop.`
|
||||
|
||||
**Ruleset 4:**
|
||||
|
||||
This tests for correct order of scanning of rules, and may trap replacement routines that scan in the wrong order. It implements a general unary multiplication engine. (Note that the input expression must be placed within underscores in this implementation.)
|
||||
|
||||
<pre>### Unary Multiplication Engine, for testing Markov Algorithm implementations
|
||||
### By Donal Fellows.
|
||||
# Unary addition engine
|
||||
_+1 -> _1+
|
||||
@ -98,16 +123,24 @@ y_ -> _
|
||||
1+_ -> 1
|
||||
_+_ ->
|
||||
</pre>
|
||||
|
||||
Sample text of:
|
||||
<code>_1111*11111_</code>
|
||||
|
||||
`_1111*11111_`
|
||||
|
||||
should generate the output:
|
||||
<code>11111111111111111111</code>
|
||||
<strong>Ruleset 5:</strong>
|
||||
A simple <a href="http://en.wikipedia.org/wiki/Turing_machine" title="link: http://en.wikipedia.org/wiki/Turing_machine" target="_blank">Turing machine</a>, implementing a three-state <a href="http://en.wikipedia.org/wiki/Busy_beaver" title="link: http://en.wikipedia.org/wiki/Busy_beaver" target="_blank">busy beaver</a>.
|
||||
The tape consists of <code>0</code>s and <code>1</code>s, the states are <code>A</code>, <code>B</code>, <code>C</code> and <code>H</code> (for <code>H</code>alt), and the head position is indicated by writing the state letter before the character where the head is. All parts of the initial tape the machine operates on have to be given in the input.
|
||||
|
||||
`11111111111111111111`
|
||||
|
||||
**Ruleset 5:**
|
||||
|
||||
A simple [Turing machine](http://en.wikipedia.org/wiki/Turing_machine "link: http://en.wikipedia.org/wiki/Turing_machine"), implementing a three-state [busy beaver](http://en.wikipedia.org/wiki/Busy_beaver "link: http://en.wikipedia.org/wiki/Busy_beaver").
|
||||
|
||||
The tape consists of `0`s and `1`s, the states are `A`, `B`, `C` and `H` (for `H`alt), and the head position is indicated by writing the state letter before the character where the head is. All parts of the initial tape the machine operates on have to be given in the input.
|
||||
|
||||
Besides demonstrating that the Markov algorithm is Turing-complete, it also made me catch a bug in the C++ implementation which wasn't caught by the first four rulesets.
|
||||
<pre>
|
||||
# Turing machine: three-state busy beaver
|
||||
|
||||
<pre># Turing machine: three-state busy beaver
|
||||
#
|
||||
# state A, symbol 0 => write 1, move right, new state B
|
||||
A0 -> 1B
|
||||
@ -126,43 +159,56 @@ B1 -> 1B
|
||||
0C1 -> H01
|
||||
1C1 -> H11
|
||||
</pre>
|
||||
|
||||
This ruleset should turn
|
||||
<code>000000A000000</code>
|
||||
|
||||
`000000A000000`
|
||||
|
||||
into
|
||||
<code>00011H1111000</code>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
`00011H1111000`
|
||||
|
||||
</section>
|
||||
# --hints--
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>markov</code> should be a function.
|
||||
testString: assert(typeof markov === 'function');
|
||||
- text: <code>markov(["A -> apple","B -> bag","S -> shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],"I bought a B of As from T S.")</code> should return "I bought a bag of apples from my brother.".
|
||||
testString: assert.deepEqual(markov(rules[0],tests[0]),outputs[0]);
|
||||
- text: <code>markov(["A -> apple","B -> bag","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],"I bought a B of As from T S.")</code> should return "I bought a bag of apples from T shop.".
|
||||
testString: assert.deepEqual(markov(rules[1],tests[1]),outputs[1]);
|
||||
- text: <code>markov(["A -> apple","WWWW -> with","Bgage -> ->.*","B -> bag","->.* -> money","W -> WW","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],"I bought a B of As W my Bgage from T S.")</code> should return "I bought a bag of apples with my money from T shop.".
|
||||
testString: assert.deepEqual(markov(rules[2],tests[2]),outputs[2]);
|
||||
- text: <code>markov(["_+1 -> _1+","1+1 -> 11+","1! -> !1",",! -> !+","_! -> _","1*1 -> x,@y","1x -> xX","X, -> 1,1","X1 -> 1X","_x -> _X",",x -> ,X","y1 -> 1y","y_ -> _","1@1 -> x,@y","1@_ -> @_",",@_ -> !_","++ -> +","_1 -> 1","1+_ -> 1","_+_ -> "],"_1111*11111_")</code> should return "11111111111111111111".
|
||||
testString: assert.deepEqual(markov(rules[3],tests[3]),outputs[3]);
|
||||
- text: <code>markov(["A0 -> 1B","0A1 -> C01","1A1 -> C11","0B0 -> A01","1B0 -> A11","B1 -> 1B","0C0 -> B01","1C0 -> B11","0C1 -> H01","1C1 -> H11"],"")</code> should return "00011H1111000".
|
||||
testString: assert.deepEqual(markov(rules[4],tests[4]),outputs[4]);
|
||||
`markov` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof markov === 'function');
|
||||
```
|
||||
|
||||
</section>
|
||||
`markov(["A -> apple","B -> bag","S -> shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],"I bought a B of As from T S.")` should return "I bought a bag of apples from my brother.".
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
```js
|
||||
assert.deepEqual(markov(rules[0], tests[0]), outputs[0]);
|
||||
```
|
||||
|
||||
<div id='js-seed'>
|
||||
`markov(["A -> apple","B -> bag","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],"I bought a B of As from T S.")` should return "I bought a bag of apples from T shop.".
|
||||
|
||||
```js
|
||||
assert.deepEqual(markov(rules[1], tests[1]), outputs[1]);
|
||||
```
|
||||
|
||||
`markov(["A -> apple","WWWW -> with","Bgage -> ->.*","B -> bag","->.* -> money","W -> WW","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],"I bought a B of As W my Bgage from T S.")` should return "I bought a bag of apples with my money from T shop.".
|
||||
|
||||
```js
|
||||
assert.deepEqual(markov(rules[2], tests[2]), outputs[2]);
|
||||
```
|
||||
|
||||
`markov(["_+1 -> _1+","1+1 -> 11+","1! -> !1",",! -> !+","_! -> _","1*1 -> x,@y","1x -> xX","X, -> 1,1","X1 -> 1X","_x -> _X",",x -> ,X","y1 -> 1y","y_ -> _","1@1 -> x,@y","1@_ -> @_",",@_ -> !_","++ -> +","_1 -> 1","1+_ -> 1","_+_ -> "],"_1111*11111_")` should return "11111111111111111111".
|
||||
|
||||
```js
|
||||
assert.deepEqual(markov(rules[3], tests[3]), outputs[3]);
|
||||
```
|
||||
|
||||
`markov(["A0 -> 1B","0A1 -> C01","1A1 -> C11","0B0 -> A01","1B0 -> A11","B1 -> 1B","0C0 -> B01","1C0 -> B11","0C1 -> H01","1C1 -> H11"],"")` should return "00011H1111000".
|
||||
|
||||
```js
|
||||
assert.deepEqual(markov(rules[4], tests[4]), outputs[4]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function markov(rules,test) {
|
||||
@ -170,15 +216,7 @@ function markov(rules,test) {
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function markov(rules,test) {
|
||||
@ -188,10 +226,10 @@ function markov(rules,test) {
|
||||
let captures = [];
|
||||
|
||||
rules.forEach(function(rule){
|
||||
let m = pattern.exec(rule);
|
||||
for (let j = 0; j < m.length; j++)
|
||||
m[j] = m[j + 1];
|
||||
captures.push(m);
|
||||
let m = pattern.exec(rule);
|
||||
for (let j = 0; j < m.length; j++)
|
||||
m[j] = m[j + 1];
|
||||
captures.push(m);
|
||||
});
|
||||
|
||||
test = origTest;
|
||||
@ -211,20 +249,18 @@ function markov(rules,test) {
|
||||
|
||||
// tail:
|
||||
let rules=[["A -> apple","B -> bag","S -> shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],
|
||||
["A -> apple","B -> bag","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],
|
||||
["A -> apple","WWWW -> with","Bgage -> ->.*","B -> bag","->.* -> money","W -> WW","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],
|
||||
["_+1 -> _1+","1+1 -> 11+","1! -> !1",",! -> !+","_! -> _","1*1 -> x,@y","1x -> xX","X, -> 1,1","X1 -> 1X","_x -> _X",",x -> ,X","y1 -> 1y","y_ -> _","1@1 -> x,@y","1@_ -> @_",",@_ -> !_","++ -> +","_1 -> 1","1+_ -> 1","_+_ -> "],
|
||||
["A0 -> 1B","0A1 -> C01","1A1 -> C11","0B0 -> A01","1B0 -> A11","B1 -> 1B","0C0 -> B01","1C0 -> B11","0C1 -> H01","1C1 -> H11"]];
|
||||
["A -> apple","B -> bag","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],
|
||||
["A -> apple","WWWW -> with","Bgage -> ->.*","B -> bag","->.* -> money","W -> WW","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],
|
||||
["_+1 -> _1+","1+1 -> 11+","1! -> !1",",! -> !+","_! -> _","1*1 -> x,@y","1x -> xX","X, -> 1,1","X1 -> 1X","_x -> _X",",x -> ,X","y1 -> 1y","y_ -> _","1@1 -> x,@y","1@_ -> @_",",@_ -> !_","++ -> +","_1 -> 1","1+_ -> 1","_+_ -> "],
|
||||
["A0 -> 1B","0A1 -> C01","1A1 -> C11","0B0 -> A01","1B0 -> A11","B1 -> 1B","0C0 -> B01","1C0 -> B11","0C1 -> H01","1C1 -> H11"]];
|
||||
let tests=["I bought a B of As from T S.",
|
||||
"I bought a B of As from T S.",
|
||||
"I bought a B of As W my Bgage from T S.",
|
||||
"_1111*11111_",
|
||||
"000000A000000"];
|
||||
"I bought a B of As from T S.",
|
||||
"I bought a B of As W my Bgage from T S.",
|
||||
"_1111*11111_",
|
||||
"000000A000000"];
|
||||
let outputs=["I bought a bag of apples from my brother.",
|
||||
"I bought a bag of apples from T shop.",
|
||||
"I bought a bag of apples with my money from T shop.",
|
||||
"11111111111111111111",
|
||||
"00011H1111000"];
|
||||
"I bought a bag of apples from T shop.",
|
||||
"I bought a bag of apples with my money from T shop.",
|
||||
"11111111111111111111",
|
||||
"00011H1111000"];
|
||||
```
|
||||
|
||||
</section>
|
||||
|
Reference in New Issue
Block a user