freeCodeCamp/curriculum/challenges/italian/10-coding-interview-prep/rosetta-code/execute-a-markov-algorithm.md

8.0 KiB

id title challengeType forumTopicId dashedName
59e09e6d412c5939baa02d16 Eseguire un algoritmo di Markov 5 302260 execute-a-markov-algorithm

--description--

Crea un interprete per un [Algoritmo di Markov](https://en.wikipedia.org/wiki/Markov algorithm "wp: Markov algorithm").

Le regole hanno questa sintassi:

[ruleset] ::= (([comment] | [rule]) [newline]+)*
[comment] ::= # {[any character]}
[rule] ::= [pattern] [whitespace] -> [whitespace] [.] [replacement]
[whitespace] ::= ([tab] | [space]) [[whitespace]]

C'è una regola per riga.

Se c'è un . (punto) prima del [replacement], allora questa è una regola di termine, in tal caso l'interprete deve fermare l'esecuzione.

Un set di regole consiste in una sequenza di regole, con commenti opzionali.

Set di regole

Usa i seguenti test sulle voci:

Set di regole 1:

# Questo file di regole è estratto da wikipedia
# http://en.wikipedia.org/wiki/Markov_Algorithm
A -> apple
B -> bag
S -> shop
T -> the
the shop -> my brother
a never used -> .terminating rule

Il testo di esempio I bought a B of As from T S. dovrebbe generare l'output di I bought a bag of apples from my brother.

Set di regole 2:

Un test della regola di termine

# Modificato leggermente dalle regole prese da Wikipedia
A -> apple
B -> bag
S -> .shop
T -> the
the shop -> my brother
a never used -> .terminating rule

Il test di esempio I bought a B of As from T S. dovrebbe generare I bought a bag of apples from T shop.

Set di regole 3:

Questo verifica il corretto ordine di sostituzione e può contenere semplici routine di sostituzione basate su espressioni regolari se non viene fatto l'escape dei caratteri speciali regexp.

# BNF Syntax testing rules
A -> apple
WWWW -> with
Bgage -> ->.*
B -> bag
->.* -> money
W -> WW
S -> .shop
T -> the
the shop -> my brother
a never used -> .terminating rule

Il testo di esempio I bought a B of As W my Bgage from T S. dovrebbe generare I bought a bag of apples with my money from T shop.

Set di regole 4:

Questo verifica il corretto ordine di scansione delle regole, e può contenere routine di sostituzione che scansionano in ordine sbagliato. Implementa un generico motore di moltiplicazione unario. (Si noti che l'espressione di input deve essere inserita all'interno di underscore in questa implementazione.)

### Macchina di moltiplicazione unitaria, per testare l'implementazione dell'algoritmo di Markov
### By Donal Fellows.
# Macchina di addizione unitaria
_+1 -> _1+
1+1 -> 11+
# Passaggio per convertire dalla separazione della moltiplicazione
# ad ordinaria addizione
1! -> !1
,! -> !+
_! -> _
# Moltiplicazione unaria, duplicando il lato sinistro tante volte quante dice il lato destro
1*1 -> x,@y
1x -> xX
X, -> 1,1
X1 -> 1X
_x -> _X
,x -> ,X
y1 -> 1y
y_ -> _
# Prossima fase di apllicazione
1@1 -> x,@y
1@_ -> @_
,@_ -> !_
++ -> +
# Pulizia dei terminali per l'addizione
_1 -> 1
1+_ -> 1
_+_ ->

Il testo di esempio _1111*11111_ dovrebbe generare l'output 11111111111111111111

Set di regole 5:

Una semplice macchina di Turing, che implementa un alacre castoro a tre stati.

Il nastro è costituito da 0 e 1, gli stati sono A, B, C e H (per Halt), e la posizione della testa è indicata scrivendo la lettera di stato prima del carattere in cui si trova la testa. Tutte le parti del nastro iniziale su cui la macchina opera devono essere fornite in ingresso.

Oltre a dimostrare che l'algoritmo di Markov è Turing-completo, mi ha anche fatto catturare un bug nell'implementazione C++ che non era stato catturato dalle prime quattro regole.

# Macchina di Turing: castoro alacre
#
# stato A, simbolo 0 => scrive 1, si sposta a destra, nuovo stato B
A0 -> 1B
# stato A, simbolo 1 => scrive 1, si sposta a sinistra, nuovo stato C
0A1 -> C01
1A1 -> C11
# state B, simbolo 0 => scrive 1, si sposta a sinistra, nuovo stato A
0B0 -> A01
1B0 -> A11
# stato B, simbolo 1 => scrive 1, si sposta a destra, nuovo stato B
B1 -> 1B
# stato C, simbolo 0 => scrive 1, si sposta a sinistra, nuovo stato B
0C0 -> B01
1C0 -> B11
# stato C, simbolo 1 => scrive 1, si sposta a sinistra, si ferma
0C1 -> H01
1C1 -> H11

Questa regola dovrebbe trasformare 000000A000000 in 00011H1111000

--hints--

markov dovrebbe essere una funzione.

assert(typeof markov === 'function');

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.") dovrebbe restituire "I bought a bag of apples from my brother.".

assert.deepEqual(markov(rules[0], tests[0]), outputs[0]);

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.") dovrebbe restituire "I bought a bag of apples from T shop.".

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.") dovrebbe restituire "I bought a bag of apples with my money from T shop.".

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_") dovrebbe restituire "11111111111111111111".

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"],"") dovrebbe restituire "00011H1111000".

assert.deepEqual(markov(rules[4], tests[4]), outputs[4]);

--seed--

--after-user-code--


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"]];
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"];
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"]

--seed-contents--

function markov(rules,test) {

}

--solutions--

function markov(rules,test) {
    let pattern = new RegExp("^([^#]*?)\\s+->\\s+(\\.?)(.*)");
    let origTest = 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);
    });

    test = origTest;
    let copy = test;
    for (let j = 0; j < captures.length; j++) {
        let c = captures[j];
        test = test.replace(c[0], c[2]);
        if (c[1]==".")
            break;
        if (test!=copy) {
            j = -1;
            copy = test;
        }
    }
    return test;
}