====== Solutii Mașina Turing ======
1. {{:aa:lab:sol:1.xlsx|}}
// Scrieți o Mașină Turing care primește un șir binar și verifică dacă începe
// și se termină cu simboluri distincte (e.g. 100110110).
//-------CONFIGURATION
name: l1e1
init: q1
accept: Y, H
q1, 0
mem0, 0, >
q1, 1
mem1, 0, >
q1, _
N, _, -
mem0, 0
mem0, 0, >
mem0, 1
mem0, 1, >
mem0, _
expect1, _, <
mem1, 0
mem1, 0, >
mem1, 1
mem1, 1, >
mem1, _
expect0, _, <
expect0, 0
Y, 0, -
expect0, 1
N, 1, -
expect1, 0
N, 0, -
expect1, 1
Y, 1, -
2. {{:aa:lab:sol:2.xlsx}}
// Rezolvați exercițiul anterior pentru input în baza 10.
//-------CONFIGURATION
name: l1e2
init: q1
accept: Y, H
q1, 0
mem0, 0, >
q1, 1
mem1, 0, >
q1, 2
mem2, 0, >
q1, 3
mem3, 0, >
q1, 4
mem4, 0, >
q1, 5
mem5, 0, >
q1, 6
mem6, 0, >
q1, 7
mem7, 0, >
q1, 8
mem8, 0, >
q1, 9
mem9, 0, >
q1, _
N, _, -
mem0, 0
mem0, 0, >
mem0, 1
mem0, 1, >
mem0, 2
mem0, 2, >
mem0, 3
mem0, 3, >
mem0, 4
mem0, 4, >
mem0, 5
mem0, 5, >
mem0, 6
mem0, 6, >
mem0, 7
mem0, 7, >
mem0, 8
mem0, 8, >
mem0, 9
mem0, 9, >
mem0, _
expectn0, _, <
mem1, 0
mem1, 0, >
mem1, 1
mem1, 1, >
mem1, 2
mem1, 2, >
mem1, 3
mem1, 3, >
mem1, 4
mem1, 4, >
mem1, 5
mem1, 5, >
mem1, 6
mem1, 6, >
mem1, 7
mem1, 7, >
mem1, 8
mem1, 8, >
mem1, 9
mem1, 9, >
mem1, _
expectn1, _, <
mem2, 0
mem2, 0, >
mem2, 1
mem2, 1, >
mem2, 2
mem2, 2, >
mem2, 3
mem2, 3, >
mem2, 4
mem2, 4, >
mem2, 5
mem2, 5, >
mem2, 6
mem2, 6, >
mem2, 7
mem2, 7, >
mem2, 8
mem2, 8, >
mem2, 9
mem2, 9, >
mem2, _
expectn2, _, <
mem3, 0
mem3, 0, >
mem3, 1
mem3, 1, >
mem3, 2
mem3, 2, >
mem3, 3
mem3, 3, >
mem3, 4
mem3, 4, >
mem3, 5
mem3, 5, >
mem3, 6
mem3, 6, >
mem3, 7
mem3, 7, >
mem3, 8
mem3, 8, >
mem3, 9
mem3, 9, >
mem3, _
expectn3, _, <
mem4, 0
mem4, 0, >
mem4, 1
mem4, 1, >
mem4, 2
mem4, 2, >
mem4, 3
mem4, 3, >
mem4, 4
mem4, 4, >
mem4, 5
mem4, 5, >
mem4, 6
mem4, 6, >
mem4, 7
mem4, 7, >
mem4, 8
mem4, 8, >
mem4, 9
mem4, 9, >
mem4, _
expectn4, _, <
mem5, 0
mem5, 0, >
mem5, 1
mem5, 1, >
mem5, 2
mem5, 2, >
mem5, 3
mem5, 3, >
mem5, 4
mem5, 4, >
mem5, 5
mem5, 5, >
mem5, 6
mem5, 6, >
mem5, 7
mem5, 7, >
mem5, 8
mem5, 8, >
mem5, 9
mem5, 9, >
mem5, _
expectn5, _, <
mem6, 0
mem6, 0, >
mem6, 1
mem6, 1, >
mem6, 2
mem6, 2, >
mem6, 3
mem6, 3, >
mem6, 4
mem6, 4, >
mem6, 5
mem6, 5, >
mem6, 6
mem6, 6, >
mem6, 7
mem6, 7, >
mem6, 8
mem6, 8, >
mem6, 9
mem6, 9, >
mem6, _
expectn6, _, <
mem7, 0
mem7, 0, >
mem7, 1
mem7, 1, >
mem7, 2
mem7, 2, >
mem7, 3
mem7, 3, >
mem7, 4
mem7, 4, >
mem7, 5
mem7, 5, >
mem7, 6
mem7, 6, >
mem7, 7
mem7, 7, >
mem7, 8
mem7, 8, >
mem7, 9
mem7, 9, >
mem7, _
expectn3, _, <
mem8, 0
mem8, 0, >
mem8, 1
mem8, 1, >
mem8, 2
mem8, 2, >
mem8, 3
mem8, 3, >
mem8, 4
mem8, 4, >
mem8, 5
mem8, 5, >
mem8, 6
mem8, 6, >
mem8, 7
mem8, 7, >
mem8, 8
mem8, 8, >
mem8, 9
mem8, 9, >
mem8, _
expectn8, _, <
mem9, 0
mem9, 0, >
mem9, 1
mem9, 1, >
mem9, 2
mem9, 2, >
mem9, 3
mem9, 3, >
mem9, 4
mem9, 4, >
mem9, 5
mem9, 5, >
mem9, 6
mem9, 6, >
mem9, 7
mem9, 7, >
mem9, 8
mem9, 8, >
mem9, 9
mem9, 9, >
mem9, _
expectn9, _, <
expectn0, 0
N, 0, -
expectn1, 1
N, 1, -
expectn2, 2
N, 2, -
expectn3, 3
N, 3, -
expectn4, 4
N, 4, -
expectn5, 5
N, 5, -
expectn6, 6
N, 6, -
expectn7, 7
N, 7, -
expectn8, 8
N, 8, -
expectn9, 9
N, 9, -
expectn0, 1
Y, 1, -
expectn0, 2
Y, 2, -
expectn0, 3
Y, 3, -
expectn0, 4
Y, 4, -
expectn0, 5
Y, 5, -
expectn0, 6
Y, 6, -
expectn0, 7
Y, 7, -
expectn0, 8
Y, 8, -
expectn0, 9
Y, 9, -
expectn1, 0
Y, 0, -
expectn1, 2
Y, 2, -
expectn1, 3
Y, 3, -
expectn1, 4
Y, 4, -
expectn1, 5
Y, 5, -
expectn1, 6
Y, 6, -
expectn1, 7
Y, 7, -
expectn1, 8
Y, 8, -
expectn1, 9
Y, 9, -
expectn2, 0
Y, 0, -
expectn2, 1
Y, 1, -
expectn2, 3
Y, 3, -
expectn2, 4
Y, 4, -
expectn2, 5
Y, 5, -
expectn2, 6
Y, 6, -
expectn2, 7
Y, 7, -
expectn2, 8
Y, 8, -
expectn2, 9
Y, 9, -
expectn3, 0
Y, 0, -
expectn3, 1
Y, 1, -
expectn3, 2
Y, 2, -
expectn3, 4
Y, 4, -
expectn3, 5
Y, 5, -
expectn3, 6
Y, 6, -
expectn3, 7
Y, 7, -
expectn3, 8
Y, 8, -
expectn3, 9
Y, 9, -
expectn4, 0
Y, 0, -
expectn4, 1
Y, 1, -
expectn4, 2
Y, 2, -
expectn4, 3
Y, 3, -
expectn4, 5
Y, 5, -
expectn4, 6
Y, 6, -
expectn4, 7
Y, 7, -
expectn4, 8
Y, 8, -
expectn4, 9
Y, 9, -
expect5, 0
Y, 0, -
expect5, 1
Y, 1, -
expect5, 2
Y, 2, -
expect5, 3
Y, 3, -
expect5, 4
Y, 4, -
expect5, 6
Y, 6, -
expect5, 7
Y, 7, -
expect5, 8
Y, 8, -
expect5, 9
Y, 9, -
expect6, 0
Y, 0, -
expect6, 1
Y, 1, -
expect6, 2
Y, 2, -
expect6, 3
Y, 3, -
expect6, 4
Y, 4, -
expect6, 5
Y, 5, -
expect6, 7
Y, 7, -
expect6, 8
Y, 8, -
expect6, 9
Y, 9, -
expect7, 0
Y, 0, -
expect7, 1
Y, 1, -
expect7, 2
Y, 2, -
expect7, 3
Y, 3, -
expect7, 4
Y, 4, -
expect7, 5
Y, 5, -
expect7, 6
Y, 6, -
expect7, 8
Y, 8, -
expect7, 9
Y, 9, -
expect8, 0
Y, 0, -
expect8, 1
Y, 1, -
expect8, 2
Y, 2, -
expect8, 3
Y, 3, -
expect8, 4
Y, 4, -
expect8, 5
Y, 5, -
expect8, 6
Y, 6, -
expect8, 7
Y, 7, -
expect8, 9
Y, 9, -
expect9, 0
Y, 0, -
expect9, 1
Y, 1, -
expect9, 2
Y, 2, -
expect9, 3
Y, 3, -
expect9, 4
Y, 4, -
expect9, 5
Y, 5, -
expect9, 6
Y, 6, -
expect9, 7
Y, 7, -
expect9, 8
Y, 8, -
3. {{:aa:lab:sol:3.xlsx}}
// 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, _, -
4. {{:aa:lab:sol:4.xlsx}}
// 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, _, -
5. {{:aa:lab:sol:5.xlsx}}
// 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, -
6. {{:aa:lab:sol:6.xlsx}}
// 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, _, >
7. {{:aa:lab:sol:7.xlsx}}
// 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, _, >
8. {{:aa:lab:sol:8.xlsx}}
// 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, _, >
9. {{:aa:lab:sol:9.xlsx}}
// 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, _, -
10. {{:aa:lab:sol:10.xlsx}}
// 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, -
11. {{:aa:lab:sol:11.xlsx}}
// 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, _, >
12. {{:aa:lab:sol:12.xlsx}}
// 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, _, >