Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
aa:lab:1 [2022/10/21 10:47]
alexandra.udrescu01
aa:lab:1 [2025/10/06 18:16] (current)
dmihai
Line 1: Line 1:
-====== ​Mașina Turing ​======+====== ​Editor de text: introducere ​======
  
-==== Simulatoare ​de Mașini Turing ====+Scopul acestui laborator este familiarizarea studenților cu editorul ​de texte pe care îl vom folosi pe parcursul semestrului pentru a ilustra în mod practic diversele concepte abordate.
  
-Simulatoarele de Mașini Turing sunt unelte foarte utile pentru vizualizarea modului de lucru al unei mașini. Fiecare simulator vine cu propriul său format de input, deci citiți cu atenție specificația.+=== Cod editor ===
  
-=== turingmachinesimulator.com ===+Descărcați scheletul de cod al editorului de text de [[https://​github.com/​cs-pub-ro/​AA-CB-public/​tree/​master/​text-editor|aici]].
  
- Un exemplu ușor de folosit este [[https://​turingmachinesimulator.com/​|acesta.]] Mașina Turing de mai sus rescrisă în formatul dorit arată așa:+=== Ncurses ===
  
-<​code>​ +Editorul este bazat pe ''​ncurses''​ -- o bibliotecă lightweight care facilitează crearea de UIs în terminal. The Linux Documentation Project menține [[https://​tldp.org/​HOWTO/​NCURSES-Programming-HOWTO/​intro.html|acest ghid]], care poate servi atât ca introducere cât și ca referință rapidă pentru diverse funcții.
-nameBinary increment +
-init: q1 +
-accept: q3+
  
-q1,0 +=== Cerințe ===
-q1,0,>+
  
-q1,1 +1. Rețineți textul sub forma unui array bidimensional;​ săgețile de la tastatură schimbă poziția cursorului în cadrul matricei. Alte taste (literecifresimboluri speciale) înlocuiesc textul de sub cursor.
-q1,1,>+
  
-q1,+2. Implementați două moduri diferite de folosire: "​view"​ și "​write"​similare cu modurile "​Normal"​ și "​Insert"​ din ''​vim''​. Modul "​view"​ e default; apăsarea tastei "​i"​ trece în "​write";​ de acoloapăsarea tastei "<Esc>"​ trece în "​view"​ (alternativ,​ puteți folosi orice alt shortcut vreți).
-q2,_,<+
  
-q2,+3. Adăugați un mod de a insera text fără suprascrie text (textul inserat "​împinge spre dreapta"​ textul existentîn limita dimensiunii unui rând în matrice).
-q3,1,-+
  
-q2,1 
-q2,0,< 
  
-q2,_ 
-q3,1,- 
-</​code>​ 
- 
-Ștergeți tot textul care apare, înlocuiți-l cu descrierea mașinii și apăsați compile. Va apărea o căsuță de input în care puteți scrie cuvântul care va fi inițial pe bandă; apoi apăsați play. 
- 
-=== jflap === 
- 
-[[https://​www.jflap.org/​|JFLAP]] este un program educațional în Java, dezvoltat pentru ilustrarea mai multor concepte de bază din computer science; îl veți găsi util și în anul 3, la Limbaje Formale și Automate. Pentru a face rost de el, completați formularul din secțiunea "Get JFLAP"​. Apoi deschideți programul, selectați "​Turing Machine"​. Aici puteți să definiți propria mașină sub formă de graf sau să deschideți una (File -> Open). Mașina Turing de mai sus în format JFLAP: 
- 
-{{:​aa:​lab:​binary_increment.zip|}} 
- 
- 
-===== Exerciții ===== 
- 
-<​note>​ 
-Exercițiile din cadrul acestui laborator vă cer să descrieți diverse Mașini Turing. 
- 
-În toate exercițiile convenția este că la începutul rulării, pe bandă se află doar inputul (restul celulelor sunt goale), iar capul de citire e poziționat pe cel mai din stânga simbol. 
- 
-Pentru exercițiile care menționează că inputul este un număr, acesta e fie numărul zero, fie începe cu o cifră diferită de 0. Cifrele numărului sunt scrise de la stânga la dreapta. 
-</​note>​ 
- 
-1. Scrieți o Mașină Turing care primește un șir binar și verifică dacă începe și se termină cu simboluri **distincte** (e.g. **1**0011011**0**). 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex1 
-init: q0 
-accept: q_accept 
- 
-// incepem cu cursorul pe prima cifra a sirului binar 
-// in starea initiala q0 citim cifra 1 
-q0, 1 
-// in aceasta situatie mergem in starea q_parcurgere1 
-// scriem 1 pe banda (ca sa nu modificam sirul) 
-// ne mutam la dreapta pentru ca vrem sa incepem parcurgerea sirului 
-q_parcurgere1,​ 1, > 
- 
-// La fel procedam cand citim 0 pe prima pozitie din sir 
-q0, 0 
-q_parcurgere0,​ 0, > 
- 
-// pe urma, starea q_parcurgereX merge pana la finalul sirului, ​ 
-// adica pana se intalneste primul caracter gol 
-// deci, pentru orice caracter 0 sau , cursorul1 se muta la dreapta 
-// fara a modifica ce e scris pe banda 
- 
-q_parcurgere1,​ 1 
-q_parcurgere1,​ 1, > 
- 
-q_parcurgere1,​ 0 
-q_parcurgere1,​ 0, > 
- 
-// cand insa parcurgerea se termina si ajungem la primul ​ 
-// spatiu gol de dupa sir, trebuie sa ne intoarcem o pozitie la stanga, 
-// adica sa ne mutam pe ultima cifra 
-// starea in care ajungem va verifica daca ultima cifra este cea opusa celei  
-// retinute in starea de parcurgere 
-q_parcurgere1,​ _ 
-q_check0, _, < 
- 
-// Similar, acelasi rationament si pentru parcurgerea ce retine ca prima cifra era 0 
- 
-q_parcurgere0,​ 1 
-q_parcurgere0,​ 1, > 
- 
-q_parcurgere0,​ 0 
-q_parcurgere0,​ 0, > 
- 
-q_parcurgere0,​ _ 
-q_check1, _, < 
- 
- 
-// Ajunsi in starea de check, verificam ce este ultima cifra a sirului 
-// (cea pe care cursorul este pozitionat) 
-// adica verificam daca este diferita de ce am retinut ca era prima cifra 
-q_check1, 0 
-q_reject, 0, - 
- 
-q_check1, 1 
-q_accept, 1, - 
- 
-q_check0, 1 
-q_reject, 1, - 
- 
-q_check0, 0 
-q_accept, 0, - 
-</​code>​ 
-</​hidden>​ 
- 
-2. Scrieți o Mașină Turing care primește un șir binar și verifică dacă are lungime impară și simbolul din mijloc este 0 (e.g. 1011**0**0011). 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex2 
-init: q0 
-accept: q_accept 
- 
-// ideea de baza este: 
-// stergem prima cifra, stergem ultima cifra 
-// repetam pana ramanem cu 1 sau 0 cifre 
-q_sterge_prima,​ 1 
-q_parcurgere,​ _, > 
- 
-q_sterge_prima,​ 0 
-q_parcurgere,​ _, > 
- 
-q_parcurgere,​ 0 
-q_parcurgere,​ 0, > 
- 
-q_parcurgere,​ 1 
-q_parcurgere,​ 1, > 
- 
-q_parcurgere,​ _ 
-q_sterge_ultima,​ _, < 
- 
-q_sterge_ultima,​ 1 
-q_parcurgere_invers,​ _, < 
- 
-q_sterge_ultima,​ 0 
-q_parcurgere_invers,​ _, < 
- 
-q_parcurgere_invers,​ 0 
-q_parcurgere_invers,​ 0, < 
- 
-q_parcurgere_invers,​ 1 
-q_parcurgere_invers,​ 1, < 
- 
-q_parcurgere_invers,​ _ 
-q0, _, > 
- 
-// daca sirul are un numar impar de cifre 
-// tebuie sa verificam daca am ramas cu o singura cifra pe banda 
-// adica: ne mutam cu o pozitie mai la dreapta si verificam ce e acolo (cifra sau spatiu gol) 
- 
-// daca e spatiu gol, pozitia anterioara era mijlocul sirului initial 
-// si daca pe acea pozitie era 1 => acceptam, daca era 0 => rejectam 
-q0, 0 
-q0_0, 0, > 
- 
-q0_0, _ 
-q_reject, _, < 
- 
-q0, 1 
-q0_1, 1, > 
- 
-q0_1, _ 
-q_accept, _, < 
- 
-// daca spatiul nu era gol, mai avem de sters cifre din ambele ​ 
-// capete pana cand dam de mijlocul sirului initial 
-q0_0, 0 
-q_sterge_prima,​ 0, < 
- 
-q0_0, 1 
-q_sterge_prima,​ 1, < 
- 
-q0_1, 0 
-q_sterge_prima,​ 0, < 
- 
-q0_1, 1 
-q_sterge_prima,​ 1, < 
- 
-// daca sirul are numar par de cifre, 
-// masina va ajunge in starea q0 cu un sir gol,  
-// caz in care trebuie sa rejecteze 
-q0, _ 
-q_reject, _, - 
- 
-</​code>​ 
-</​hidden>​ 
- 
-3. Rezolvați primele două exerciții pentru input în baza 10. 
- 
-4. Scrieți o Mașină Turing care primește un șir binar și lasă pe bandă complementul lui (e.g. "​100110100"​ -> "​011001011"​) 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex4 
-init: q0 
-accept: q_accept 
- 
-// idee: parcurgem o data sirul si schimbam 0 in 1 si 1 in 0 
- 
-q0, _ 
-q_accept, _, < 
- 
-q0, 1 
-q0, 0, > 
- 
-q0, 0 
-q0, 1, > 
- 
- 
-</​code>​ 
-</​hidden>​ 
- 
-5. Scrieți o Mașină Turing care curăță toată banda (atât la stânga cât și la dreapta) și apoi lasă scris doar "​1"​. 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex5 
-init: q0 
-accept: q_accept 
- 
-q0, 0 
-q0, 0, < 
- 
-q0, 1 
-q0, 1, < 
- 
-q0, _ 
-q, _, > 
- 
-q, 0 
-q, _, > 
- 
-q, 1 
-q, _, > 
- 
-q, _ 
-q_accept, 1, - 
- 
-</​code>​ 
-</​hidden>​ 
- 
-6. Scrieți o Mașină Turing care inversează cuvântul primit pe bandă. 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex6 
-init: q0 
-accept: q_accept 
- 
-// extra transition for numbers with only 2 digits 
-q0, _ 
-replace, X, < 
- 
-q0, 1 
-take1, _, > 
- 
-take1, 0 
-take1, 0, > 
- 
-take1, 1 
-take1, 1, > 
- 
-take1, _ 
-q0R, U, < 
- 
-q0, 0 
-take0, _, > 
- 
-take0, 0 
-take0, 0, > 
- 
-take0, 1 
-take0, 1, > 
- 
-take0, _ 
-q0R, Z, < 
- 
-q0R, 1 
-take1R, _, < 
- 
-take1R, 0 
-take1R, 0, < 
- 
-take1R, 1 
-take1R, 1, < 
- 
-take1R, _ 
-q0, U, > 
- 
-q0R, 0 
-take0R, _, < 
- 
-take0R, 0 
-take0R, 0, < 
- 
-take0R, 1 
-take0R, 1, < 
- 
-take0R, _ 
-q0, Z, > 
- 
-// a spce remains in the middle of the word 
-q0R, _ 
-go_start, X, < 
- 
-go_start, _ 
-replace, _, > 
- 
-go_start, Z 
-go_start, Z, < 
- 
-go_start, U 
-go_start, U, < 
- 
-replace, Z 
-replace0, _, > 
- 
-replace, X 
-replace_current,​ _, > 
- 
-replace, U 
-replace1, _, > 
- 
-replace0, Z 
-replace0, 0, > 
- 
-replace0, U 
-replace1, 0, > 
- 
-replace1, Z 
-replace0, 1, > 
- 
-replace1, U 
-replace1, 1, > 
- 
-replace1, X 
-replace_current,​ 1, > 
- 
-replace0, X 
-replace_current,​ 0, > 
- 
-replace_current,​ Z 
-replace_current,​ 0, > 
- 
-replace_current,​ U 
-replace_current,​ 1, > 
- 
-replace_current,​ _ 
-q_accept, _, < 
-</​code>​ 
-</​hidden>​ 
- 
-7. Scrieți o Mașină Turing care primește un șir de "​X"​-uri și verifică dacă lungimea acestuia este o putere a lui 2. 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex7 
-init: q0 
-accept: q_accept 
- 
-// idea: 
-// start with one zero, then double the number of zeros as shown below: 
-// 0000XXXXX <- 4 zeros 
-// A000AXXXX 
-// AA00AAXXX 
-// AAA0AAAXX 
-// AAAAAAAXX 
-// 0000000XX <- 8 zeros 
- 
-// 0000000XX 
-// A000000XX 
-// A000000AX 
-// AA00000AX 
-// AA00000AA 
-// AAA0000AA -> we can't find another X to match with the newely added A => reject 
- 
-// to accept, the number must look like: AAAAAAAA before turning the A to 0 
- 
- 
-// start by making the first character a 0 
-q0, X 
-double0, 0, - 
- 
-// if there is no more zero that should be doubled, 
-// it means we made all of the characters to A 
-// which means that the lenght of the input was 2^k 
-double0, _ 
-q_accept, _, - 
- 
-// try to find a zero and mark it with A 
-double0, A 
-double0, A, > 
- 
-double0, 0 
-findX, A, > 
- 
-// once a zero was found and marked, search for its pair/search for an X 
-findX, A 
-findX, A, > 
- 
-findX, 0 
-findX, 0, > 
- 
-// when a pair is found, mark it and return to the start of the tape 
-findX, X 
-goback, A, < 
- 
-// when no other X can be found to double the last 0 that was turned to an A 
-// then it means we don't have a length of 2^k, so reject 
-findX, _ 
-q_reject, _, - 
- 
-goback, A 
-goback, A, < 
- 
-goback, 0 
-goback, 0, < 
- 
-goback, _ 
-double0, _, > 
- 
-// after doubling all the zeros at the begining 
-// change all As to zeros 
-double0, X 
-turnAto0, X, < 
- 
-turnAto0, A 
-turnAto0, 0, < 
- 
-turnAto0, _ 
-double0, _, > 
- 
-</​code>​ 
-</​hidden>​ 
- 
-8. Scrieți o Mașină Turing care primește un șir de paranteze "​(",​ "​)"​ și verifică dacă sunt echilibrate. 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex8 
-init: q0 
-accept: q_accept 
- 
-// (((()))()) 
-// idea: gasim ultima paranteza '​('​ si o combinam cu prima paranteza '​)'​ care o urmeza 
-// parantezele deja imperecheate se marcheaza cu X 
-q0, ( 
-q0, (, > 
- 
-q0, ) 
-q0, ), > 
- 
-q0, _ 
-find(, _, < 
- 
-q0, X 
-q0, X, > 
- 
-find(, X 
-find(, X, < 
- 
-find(, ) 
-find(, ), < 
- 
-find(, ( 
-find), X, > 
- 
-find), X 
-find), X, > 
- 
-find), ( 
-find), (, > 
- 
-find), ) 
-gostart, X, < 
- 
-find), _ 
-q_reject, _, - 
- 
- 
-gostart, ) 
-gostart, ), < 
- 
-gostart, ( 
-gostart, (, < 
- 
-gostart, X 
-gostart, X, < 
- 
-gostart, _ 
-q0, _, > 
- 
-// acceptam cand nu mai exista paranteze ( si doar X-uri au ramas pe banda 
-find(, _ 
-search_nonX,​ _, > 
- 
-search_nonX,​ X 
-search_nonX,​ X, > 
- 
-search_nonX,​ ( 
-q_reject, (, - 
- 
-search_nonX,​ ) 
-q_reject, ), - 
- 
-search_nonX,​ _ 
-q_accept, _, - 
- 
-</​code>​ 
-</​hidden>​ 
- 
-9. Scrieți o Mașină Turing care primește un număr în baza 2 și verifică dacă e divizibil cu 5. 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex9 
-init: q0 
-accept: rest0 
- 
-q0, 1 
-rest1, 1, > 
- 
-q0, 0 
-rest0, 0, > 
- 
-rest1, 0 
-rest2, 0, > 
- 
-rest1, 1 
-rest3, 1, > 
- 
-rest2, 0 
-rest4, 0, > 
- 
-rest2, 1 
-rest0, 1, > 
- 
-rest3, 0 
-rest1, 0, > 
- 
-rest3, 1 
-rest2, 1, > 
- 
-rest4, 0 
-rest3, 0, > 
- 
-rest4, 1 
-rest4, 1, > 
- 
-rest0, 0 
-rest0, 0, > 
- 
-rest0, 1 
-rest1, 1, > 
- 
-</​code>​ 
-</​hidden>​ 
- 
-10. Scrieți o Mașină Turing care primește un cuvânt binar, găsește primul simbol "​0"​ și inserează un "​1"​ în stânga lui (deci tot ce apare la dreapta va trebui mutat cu o poziție). 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex10 
-init: q0 
-accept: q_accept 
- 
-// parcurgem sirul pana gasim un zero fara a il modifica 
-q0, 1 
-q0, 1, > 
- 
-// gasim un 0, scriem 1 in locul lui peste el 
-// si urmeaza sa mutam toate celelalte caractere cu o pozitie la dreapta 
-q0, 0 
-q_replace_0,​ 1, > 
- 
-// daca nu auu existat zerouri, acceptam fara a face modificari 
-q0, _ 
-q_accept, _, - 
- 
-// schimbam cifra curenta cu caracterul retinut in stare 
-// si o retinem ca sa o putem scrie pe pozitia urmatoare 
-q_replace_0,​ 0 
-q_replace_0,​ 0, > 
- 
-q_replace_0,​ 1 
-q_replace_1,​ 0, > 
- 
-q_replace_1,​ 0 
-q_replace_0,​ 1, > 
- 
-q_replace_1,​ 1 
-q_replace_1,​ 1, > 
- 
-// cand ajungem la finalul sirului, doar scriem caracterul retinut si acceptam 
-q_replace_0,​ _ 
-q_accept, 0, - 
- 
-q_replace_1,​ _ 
-q_accept, 1, - 
- 
-</​code>​ 
-</​hidden>​ 
- 
-11. Scrieți o Mașină Turing care primește două numere în baza 2, big-endian, separate de un # și lasă pe bandă suma lor (e.g. "​1011#​11001"​ -> "​100100"​). 
- 
-<​hidden>​ 
-<​code>​ 
- 
-name: ex11 
-init: q1 
-accept: halt 
- 
-// q1 parcurge primul numar 
-// pana la separatorul dintre numere 
-q1,0 
-q1,0,> 
- 
-q1,1 
-q1,1,> 
- 
-q1,# 
-get_adding_number,#,<​ 
- 
-// get_adding_number ia urmatorul digit din primul numar 
-// pentru a-l adauga la al doilea numar, si il inlocuieste cu 
-// un X (care inseamna ca am folosit digit-ul) 
-get_adding_number,​0 
-go_second_0,​X,>​ 
- 
-get_adding_number,​1 
-go_second_1,​X,>​ 
- 
-get_adding_number,​X 
-get_adding_number,​X,<​ 
- 
-get_adding_number,​_ 
-finish,​_,>​ 
- 
-// go_second_0 si go_second_1 parcurge pana la al doilea numar 
-// retinand cat trebuie adaugat 
-go_second_0,#​ 
-go_to_place_0,#,>​ 
- 
-go_second_0,​X 
-go_second_0,​X,>​ 
- 
-go_second_1,#​ 
-go_to_place_1,#,>​ 
- 
-go_second_1,​X 
-go_second_1,​X,>​ 
- 
-// go_to_place_0 si go_to_place_1 parcurg al doilea numar pana 
-// unde am ajuns cu adunarea (cifrele deja parcurse au fost 
-// inlocuite cu a si b in loc de 0 si 1) 
-go_to_place_0,​0 
-go_to_place_0,​0,>​ 
- 
-go_to_place_0,​1 
-go_to_place_0,​1,>​ 
- 
-go_to_place_0,​a 
-add_0,​a,<​ 
- 
-go_to_place_0,​b 
-add_0,​b,<​ 
- 
-go_to_place_0,​_ 
-add_0,​_,<​ 
- 
-go_to_place_1,​0 
-go_to_place_1,​0,>​ 
- 
-go_to_place_1,​1 
-go_to_place_1,​1,>​ 
- 
-go_to_place_1,​a 
-add_1,​a,<​ 
- 
-go_to_place_1,​b 
-add_1,​b,<​ 
- 
-go_to_place_1,​_ 
-add_1,​_,<​ 
- 
-// go_first_number se intoarce spre dreapta la primul numar 
-go_first_number,​0 
-go_first_number,​0,<​ 
- 
-go_first_number,​1 
-go_first_number,​1,<​ 
- 
-go_first_number,​a 
-go_first_number,​a,<​ 
- 
-go_first_number,​b 
-go_first_number,​b,<​ 
- 
-go_first_number,#​ 
-get_adding_number,#,<​ 
- 
-// adaugam 0 la numarul curent si inlocuim numarul cu a/b pt 0/1 
-add_0,0 
-go_first_number,​a,<​ 
- 
-add_0,1 
-go_first_number,​b,<​ 
- 
-add_0,# 
-translate_right_a,#,>​ 
- 
-// adaugam 1 la numarul curent si inlocuim numarul cu a/b pt 0/1 
-add_1,0 
-go_first_number,​b,<​ 
- 
-add_1,1 
-add_second_1,​a,<​ 
- 
-add_1,# 
-translate_right_b,#,>​ 
- 
-add_second_1,​0 
-go_first_number,​1,<​ 
- 
-add_second_1,​1 
-add_second_1,​0,<​ 
- 
-add_second_1,#​ 
-translate_right_1,#,>​ 
- 
-// functii pentru translatarea la dreapta a celui de-al doilea numar, 
-// unde caracterele posibile pot fi 0,1,a,b 
-translate_right_0,​0 
-translate_right_0,​0,>​ 
- 
-translate_right_0,​1 
-translate_right_1,​0,>​ 
- 
-translate_right_0,​a 
-translate_right_a,​0,>​ 
- 
-translate_right_0,​b 
-translate_right_b,​0,>​ 
- 
-translate_right_0,​_ 
-go_first_number,​0,<​ 
- 
-translate_right_1,​0 
-translate_right_0,​1,>​ 
- 
-translate_right_1,​1 
-translate_right_1,​1,>​ 
- 
-translate_right_1,​a 
-translate_right_a,​1,>​ 
- 
-translate_right_1,​b 
-translate_right_b,​1,>​ 
- 
-translate_right_1,​_ 
-go_first_number,​1,<​ 
- 
-translate_right_a,​0 
-translate_right_0,​a,>​ 
- 
-translate_right_a,​1 
-translate_right_1,​a,>​ 
- 
-translate_right_a,​a 
-translate_right_a,​a,>​ 
- 
-translate_right_a,​b 
-translate_right_b,​a,>​ 
- 
-translate_right_a,​_ 
-go_first_number,​a,<​ 
- 
-translate_right_b,​0 
-translate_right_0,​b,>​ 
- 
-translate_right_b,​1 
-translate_right_1,​b,>​ 
- 
-translate_right_b,​a 
-translate_right_a,​b,>​ 
- 
-translate_right_b,​b 
-translate_right_b,​b,>​ 
- 
-translate_right_b,​_ 
-go_first_number,​b,<​ 
- 
-// cand ajungem in finish trebuie sa facem clean-up la banda 
-// sa stergem X-uri si # 
-// sa transformam a in 0 si b in 1 
- 
-finish,X 
-finish,​_,>​ 
- 
-finish,# 
-finish,​_,>​ 
- 
-finish,1 
-finish,​1,>​ 
- 
-finish,0 
-finish,​0,>​ 
- 
-finish,a 
-finish,​0,>​ 
- 
-finish,b 
-finish,​1,>​ 
- 
-finish,_ 
-halt,_,- 
-</​code>​ 
-</​hidden>​ 
- 
-12. Scrieți o Mașină Turing care primește un șir binar și lasă pe bandă, după un caracter "#",​ numărul de 0-uri, în bază 2 (e.g. "​100010110"​ -> "​100010110#​101"​). 
- 
-<​hidden>​ 
-<​code>​ 
-name: ex12 
-init: q1 
-accept: halt 
- 
-// q1 parcurge primul numar 
-// pana la final 
-q1,0 
-q1,0,> 
- 
-q1,1 
-q1,1,> 
- 
-q1,_ 
-init,#,> 
- 
-// init adauga incepe numaratoare de la 0 
-init,_ 
-find_0,​0,<​ 
- 
-// find_0 cauta un 0 sa il numere 
-find_0,1 
-find_0,​1,<​ 
- 
-find_0,X 
-find_0,​X,<​ 
- 
-find_0,# 
-find_0,#,<​ 
- 
-find_0,0 
-go_add_1,​X,>​ 
- 
-find_0,_ 
-finish,​_,>​ 
- 
-go_add_1,0 
-go_add_1,​0,>​ 
- 
-go_add_1,1 
-go_add_1,​1,>​ 
- 
-go_add_1,X 
-go_add_1,​X,>​ 
- 
-go_add_1,# 
-go_add_1,#,>​ 
- 
-go_add_1,_ 
-add_1,​_,<​ 
- 
-// go_first_number se intoarce spre dreapta la primul numar 
-go_first_number,​0 
-go_first_number,​0,<​ 
- 
-go_first_number,​1 
-go_first_number,​1,<​ 
- 
-go_first_number,#​ 
-find_0,#,<​ 
- 
-// adaugam 1 la counter 
-add_1,0 
-go_first_number,​1,<​ 
- 
-add_1,1 
-add_1,​0,<​ 
- 
-add_1,# 
-translate_right_1,#,>​ 
- 
-// functii pentru translatarea la dreapta a celui de-al doilea numar, 
-// unde caracterele posibile pot fi 0,1,a,b 
-translate_right_0,​0 
-translate_right_0,​0,>​ 
- 
-translate_right_0,​1 
-translate_right_1,​0,>​ 
- 
-translate_right_0,​_ 
-go_first_number,​0,<​ 
- 
-translate_right_1,​0 
-translate_right_0,​1,>​ 
- 
-translate_right_1,​1 
-translate_right_1,​1,>​ 
- 
-translate_right_1,​_ 
-go_first_number,​1,<​ 
- 
-// cand ajungem in finish trebuie sa facem clean-up la banda 
-finish,X 
-finish,​0,>​ 
- 
-finish,1 
-finish,​1,>​ 
- 
-finish,0 
-finish,​0,>​ 
- 
-finish,# 
-halt,#,- 
-</​code>​ 
-</​hidden>​