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:sol:1 [2024/10/05 16:03]
dmihai
aa:lab:sol:1 [2024/10/16 23:18] (current)
dmihai
Line 1: Line 1:
 ====== Solutii Mașina Turing ====== ====== Solutii Mașina Turing ======
  
-1.+1. {{:​aa:​lab:​sol:​1.xlsx|}}
  
 +<​hidden>​
 <​code>​ <​code>​
  // Scrieți o Mașină Turing care primește un șir binar și verifică dacă începe  // Scrieți o Mașină Turing care primește un șir binar și verifică dacă începe
Line 55: Line 56:
 Y, 1, - Y, 1, -
 </​code>​ </​code>​
 +</​hidden>​
  
-2.+2. {{:​aa:​lab:​sol:​2.xlsx}} 
 + 
 +<​hidden>​
 <​code>​ <​code>​
 // Rezolvați exercițiul anterior pentru input în baza 10. // Rezolvați exercițiul anterior pentru input în baza 10.
Line 749: Line 753:
 Y, 8, - Y, 8, -
 </​code>​ </​code>​
 +</​hidden>​
 +
 +3. {{:​aa:​lab:​sol:​3.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// 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. 101100011).
 +name: l1e3
 +init: start
 +accept: H, Y
 +
 +start, 0
 +got0, _, >
 +
 +start, 1
 +find_end, _, >
 +
 +start, _
 +N, _, -
 +
 +
 +find_end, 0
 +find_end, 0, >
 +
 +find_end, 1
 +find_end, 1, >
 +
 +find_end, _
 +delete_last,​ _, <
 +
 +
 +delete_last,​ 0
 +reset, _, <
 +
 +delete_last,​ 1
 +reset, _, <
 +
 +// input was just "​1"​
 +delete_last,​ _
 +N, _, -
 +
 +
 +reset, 0
 +reset, 0, <
 +
 +reset, 1
 +reset, 1, <
 +
 +reset, _
 +start, _, >
 +
 +
 +got0, 0
 +find_end, 0, >
 +
 +got0, 1
 +find_end, 1, >
 +
 +got0, _
 +Y, _, -
 +</​code>​
 +</​hidden>​
 +
 +4. {{:​aa:​lab:​sol:​4.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// Scrieți o Mașină Turing care primește un șir binar și
 +// lasă pe bandă complementul lui (e.g. “100110100” → “011001011”)
 +name: l1e4
 +init: start
 +accept: H, Y
 +
 +start, 0
 +start, 1, >
 +
 +start, 1
 +start, 0, >
 +
 +start, _
 +H, _, -
 +</​code>​
 +</​hidden>​
 +
 +5. {{:​aa:​lab:​sol:​5.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// 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”.
 +name: l1e5
 +init: start
 +accept: H, Y
 +
 +start, 0
 +start, 0, <
 +
 +start, 1
 +start, 1, <
 +
 +start, _
 +delete, _, >
 +
 +
 +delete, 0
 +delete, _, >
 +
 +delete, 1
 +delete, _, >
 +
 +delete, _
 +H, 1, -
 +</​code>​
 +</​hidden>​
 +
 +6. {{:​aa:​lab:​sol:​6.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// Scrieți o Mașină Turing care inversează cuvântul primit pe bandă.
 +name: l1e6
 +init: start
 +accept: H, Y
 +
 +// mașina o să memoreze primul simbol, o să-l șteargă, apoi va parcuge inputul
 +// până ajunge la final, lasă un spațiu liber și plasează simbolul memorat pe
 +// prima celula goală, după spațiul liber; apoi revine la începutul șirului,
 +// făcând recursiv această acțiune.
 +start, 0
 +mem0, _, >
 +
 +start, 1
 +mem1, _, >
 +
 +start, _
 +H, _, >
 +
 +
 +mem0, 0
 +mem0, 0, >
 +
 +mem0, 1
 +mem0, 1, >
 +
 +mem0, _
 +write_at_end_0,​ _, >
 +
 +
 +mem1, 0
 +mem1, 0, >
 +
 +mem1, 1
 +mem1, 1, >
 +
 +mem1, _
 +write_at_end_1,​ _, >
 +
 +
 +write_at_end_0,​ 0
 +write_at_end_0,​ 0, >
 +
 +write_at_end_0,​ 1
 +write_at_end_0,​ 1, >
 +
 +write_at_end_0,​ _
 +reset, 0, <
 +
 +
 +write_at_end_1,​ 0
 +write_at_end_1,​ 0, >
 +
 +write_at_end_1,​ 1
 +write_at_end_1,​ 1, >
 +
 +write_at_end_1,​ _
 +reset, 1, <
 +
 +
 +reset, 0
 +reset, 0, <
 +
 +reset, 1
 +reset, 1, <
 +
 +reset, _
 +reset2, _, <
 +
 +
 +reset2, 0
 +reset2, 0, <
 +
 +reset2, 1
 +reset2, 1, <
 +
 +reset2, _
 +start, _, >
 +</​code>​
 +</​hidden>​
 +
 +7. {{:​aa:​lab:​sol:​7.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// 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.
 +name: l1e7
 +init: start
 +accept: H, Y
 +
 +// Vom folosi simbolul D pentru a marca X-uri (nu le ștergem ca să putem știi
 +// unde începe și se termină șirul (la simboluri blank).
 +//
 +// Vom șterge 1 din două X-uri, apoi ne vom întoarce la început și vom repeta
 +// procesul.
 +//
 +// Dacă găsim un nr. impar de X-uri, inputul e respins; în afară de cazul în
 +// găsim un singur X (singura putere impară a lui 2), caz în care acceptăm.
 +start, X
 +check_if_just_one_X,​ D, >
 +
 +start, D
 +start, D, >
 +
 +// 0 nu e o putere a lui 2.
 +start, _
 +N, _, -
 +
 +
 +check_if_just_one_X,​ D
 +check_if_just_one_X,​ D, >
 +
 +check_if_just_one_X,​ _
 +Y, _, -
 +
 +check_if_just_one_X,​ X
 +skip, X, -
 +
 +
 +skip, X
 +delete, X, >
 +
 +skip, D
 +skip, D, >
 +
 +skip, _
 +N, _, -
 +
 +
 +delete, X
 +skip, D, >
 +
 +delete, D
 +delete, D, >
 +
 +delete, _
 +reset, _, <
 +
 +
 +reset, X
 +reset, X, <
 +
 +reset, D
 +reset, D, <
 +
 +reset, _
 +start, _, >
 +</​code>​
 +</​hidden>​
 +
 +8. {{:​aa:​lab:​sol:​8.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// Scrieți o Mașină Turing care primește un șir de paranteze “(”, “)” ​
 +// și verifică dacă sunt echilibrate.
 +name: l1e8
 +init: start
 +accept: H, Y
 +
 +
 +// Whenever we find an open paranthesis,​ we search for a match and delete it.
 +// As before, we don't want to include blank symbols in the middle of the tape,
 +// so we'll delete it by overwriting it with the symbol "​D"​.
 +start, )
 +N, ), -
 +
 +start, (
 +find_), _, >
 +
 +start, D
 +start, _, >
 +
 +start, _
 +Y, _, -
 +
 +
 +find_), (
 +find_), (, >
 +
 +find_), D
 +find_), D, >
 +
 +find_), )
 +reset, D, <
 +
 +
 +reset, (
 +reset, (, <
 +
 +reset, )
 +reset, ), <
 +
 +reset, D
 +reset, D, <
 +
 +reset, _
 +start, _, >
 +</​code>​
 +</​hidden>​
 +
 +9. {{:​aa:​lab:​sol:​9.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// Scrieți o Mașină Turing care primește un număr în baza 2 și verifică dacă
 +// e divizibil cu 5.
 +name: l1e9
 +init: r0
 +accept: H, Y
 +
 +// Ideea este să reținem în starea curentă, resturile împărțirii la 5, care sunt
 +// cinci la număr: 0, 1, 2, 3, 4
 +// Putem să ne imaginăm că la orice moment de timp, am citit primii biți din
 +// input, formând un număr n, despre care ținem minte doar restul împărțirii
 +// la 5, numit r; când ne mutăm la dreapta, citind un nou bit din input,
 +// avem de fapt un nou număr:
 +//  - dacă citim 0, avem n * 2
 +//  - dacă citim 1, avem n * 2 + 1
 +//
 +// Dar nu trebuie să ținem minte tot numărul, doar restul împărțirii la 5; deci,
 +// de exemplu, dacă avem r = 3, și citim un 1, atunci r devine 2
 +// (adică 3 * 2 + 1 mod 5).
 +r0, 0
 +r0, 0, >
 +
 +r0, 1
 +r1, 1, >
 +
 +r0, _
 +Y, _, -
 +
 +
 +r1, 0
 +r2, 0, >
 +
 +r1, 1
 +r3, 1, >
 +
 +r1, _
 +N, _, -
 +
 +
 +r2, 0
 +r4, 0, >
 +
 +r2, 1
 +r0, 1, >
 +
 +r2, _
 +N, _, -
 +
 +
 +r3, 0
 +r1, 0, >
 +
 +r3, 1
 +r2, 1, >
 +
 +r3, _
 +N, _, -
 +
 +
 +r4, 0
 +r3, 0, >
 +
 +r4, 1
 +r4, 1, >
 +
 +r1, _
 +N, _, -
 +</​code>​
 +</​hidden>​
 +
 +10. {{:​aa:​lab:​sol:​10.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// 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).
 +name: l1e10
 +init: start
 +accept: H, Y
 +
 +start, 0
 +shift_input0,​ 1, >
 +
 +start, 1
 +start, 1, >
 +
 +start, _
 +H, _, -
 +
 +
 +shift_input0,​ 0
 +shift_input0,​ 0, >
 +
 +shift_input0,​ 1
 +shift_input1,​ 0, >
 +
 +shift_input0,​ _
 +H, 0, -
 +
 +
 +shift_input1,​ 0
 +shift_input0,​ 1, >
 +
 +shift_input1,​ 1
 +shift_input1,​ 1, >
 +
 +shift_input1,​ _
 +H, 1, -
 +</​code>​
 +</​hidden>​
 +
 +11. {{:​aa:​lab:​sol:​11.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// 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”).
 +name: l1e11
 +init: start
 +accept: H, Y
 +
 +// E mai ușor să adunăm cel de-al doilea număr la primul, creând rezultatul
 +// "​peste"​ primul număr (altfel în cazul în care al doilea număr e mai scurt,
 +// sau adunarea produce overflow, ar trebui să shiftăm rezultatul).
 +// Ca să știm la ce cifră din primul număr am jos, vom folosi simboluri ​
 +// auxiliare Z și O (pentru 0 și 1), cât lucrăm, și le vom înlocui abia la
 +// final.
 +start, 0
 +go_to_#, 0, >
 +
 +start, 1
 +go_to_#, 1, >
 +
 +start, #
 +H, _, >
 +
 +
 +go_to_#, 0
 +go_to_#, 0, >
 +
 +go_to_#, 1
 +go_to_#, 1, >
 +
 +go_to_#, Z
 +go_to_#, Z, >
 +
 +go_to_#, O
 +go_to_#, O, >
 +
 +go_to_#, #
 +go_to_end, #, >
 +
 +
 +go_to_end, 0
 +go_to_end, 0, >
 +
 +go_to_end, 1
 +go_to_end, 1, >
 +
 +go_to_end, _
 +get_lsd, _, <
 +
 +
 +get_lsd, 0
 +lsd_0, _, <
 +
 +get_lsd, 1
 +lsd_1, _, <
 +
 +
 +// n-au mai rămas cifre de prelucrat din al doilea număr
 +get_lsd, #
 +rewrite_first,​ _, <
 +
 +lsd_0, 0
 +lsd_0, 0, <
 +
 +lsd_0, 1
 +lsd_0, 1, <
 +
 +lsd_0, #
 +lsd_0_after_#,​ #, <
 +
 +
 +lsd_1, 0
 +lsd_1, 0, <
 +
 +lsd_1, 1
 +lsd_1, 1, <
 +
 +lsd_1, #
 +lsd_1_after_#,​ #, <
 +
 +
 +// Sărim peste cifrele "deja afectate"​.
 +lsd_0_after_#,​ Z
 +lsd_0_after_#,​ Z, <
 +
 +lsd_0_after_#,​ O
 +lsd_0_after_#,​ O, <
 +
 +
 +lsd_1_after_#,​ Z
 +lsd_1_after_#,​ Z, <
 +
 +lsd_1_after_#,​ O
 +lsd_1_after_#,​ O, <
 +
 +
 +// marcăm o nouă cifră prelucrată din primul număr
 +lsd_0_after_#,​ 0
 +go_to_#, Z, >
 +
 +lsd_0_after_#,​ 1
 +go_to_#, O, >
 +
 +lsd_0_after_#,​ _
 +go_to_#, Z, >
 +
 +
 +lsd_1_after_#,​ 0
 +go_to_#, O, >
 +
 +// acum ar trebui să intrăm într-un mod de "​binary increment"​ al primului număr,
 +// în care incrementăm tot spre stânga, fără a marca cifrele!
 +lsd_1_after_#,​ 1
 +increment, Z, <
 +
 +increment, 1
 +increment, 0, <
 +
 +increment, 0
 +go_to_#, 1, >
 +
 +increment, _
 +go_to_#, 1, >
 +
 +lsd_1_after_#,​ _
 +go_to_#, O, >
 +
 +
 +rewrite_first,​ 0
 +rewrite_first,​ 0, <
 +
 +rewrite_first,​ 1
 +rewrite_first,​ 1, <
 +
 +rewrite_first,​ Z
 +rewrite_first,​ 0, <
 +
 +rewrite_first,​ O
 +rewrite_first,​ 1, <
 +
 +rewrite_first,​ _
 +H, _, >
 +</​code>​
 +</​hidden>​
 +
 +12. {{:​aa:​lab:​sol:​12.xlsx}}
 +
 +<​hidden>​
 +<​code>​
 +// 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”).
 +name: l1e12
 +init: start
 +accept: H, Y
 +
 +// De fiecare dată când găsim un 0, vom incrementa un contor.
 +// De data asta, ne vom folosi de soluția de la ex. 10, ca să shiftăm contorul
 +// spre dreapta, de fiecare dată când mai trebuie adăugat un bit.
 +// Nu putem șterge 0-urile, dar o să le marcăm temporar cu Z.
 +
 +start, 1
 +start, 1, >
 +
 +start, 0
 +goto_counter,​ Z, >
 +
 +start, Z
 +start, Z, >
 +
 +start, #
 +restore_0, #, <
 +
 +// dacă nu am găsit niciun 0, trebuie lăsat numărul "​0"​ pe bandă.
 +start, _
 +w0, #, >
 +
 +
 +w0, _
 +H, 0, -
 +
 +
 +goto_counter,​ 0
 +goto_counter,​ 0, >
 +
 +goto_counter,​ 1
 +goto_counter,​ 1, >
 +
 +// "​inițializăm"​ contorul prima dată când ajungem la sfârșit
 +goto_counter,​ _
 +goto_end, #, >
 +
 +goto_counter,​ #
 +goto_end, #, >
 +
 +
 +goto_end, 0
 +goto_end, 0, >
 +
 +goto_end, 1
 +goto_end, 1, >
 +
 +goto_end, _
 +increment, _, <
 +
 +
 +increment, 0
 +reset, 1, <
 +
 +increment, 1
 +increment, 0, <
 +
 +increment, #
 +start_shift,​ #, >
 +
 +
 +start_shift,​ 1
 +shift1, 1, >
 +
 +start_shift,​ 0
 +shift0, 1, >
 +
 +// asta se poate întâmpla doar când inițializem contorul
 +start_shift,​ _
 +reset, 1, <
 +
 +
 +shift1, 0
 +shift0, 1, >
 +
 +shift1, 1
 +shift1, 1, >
 +
 +shift1, _
 +reset, 1, <
 +
 +
 +shift0, 0
 +shift0, 0, >
 +
 +shift0, 1
 +shift1, 0, >
 +
 +shift0, _
 +reset, 0, <
 +
 +
 +reset, 0
 +reset, 0, <
 +
 +reset, 1
 +reset, 1, <
 +
 +reset, #
 +reset, #, <
 +
 +reset, Z
 +reset, Z, <
 +
 +reset, _
 +start, _, >
 +
 +
 +restore_0, Z
 +restore_0, 0, <
 +
 +restore_0, 1
 +restore_0, 1, <
 +
 +restore_0, _
 +H, _, >
 +
 +</​code>​
 +</​hidden>​
 +