Domanda 8 delle tracce

Impara a programmare una macchina di Turing

Parti dall'idea, scegli gli stati e scrivi le transizioni. Segui l'esempio guidato, poi prova la tua macchina nel simulatore o esplora le soluzioni delle tracce.

Nastro, testina e stati

Una macchina di Turing legge e scrive su un nastro diviso in celle. La testina indica la cella corrente; lo stato ricorda in quale fase del calcolo si trova la macchina.

La tabella δ\delta è il programma. Ogni riga specifica: cosa leggere, cosa scrivere, dove spostarsi e quale stato assumere.

Con input 1011, la configurazione iniziale è:

▷  1  0  1  1  ⊔  ⊔  …
↑
testina (stato iniziale s)

▹\triangleright segna l'inizio del nastro; ⊔\sqcup indica una cella vuota. La testina parte su ▹\triangleright, nello stato ss.

Come leggere una transizione

La macchina si descrive con M=(K,Σ,δ,s)M=(K,\Sigma,\delta,s): stati, alfabeto, transizioni e stato iniziale.

Una regola δ(p,σ)=(q,ρ,D)\delta(p,\sigma)=(q,\rho,D) si legge così: nello stato pp, se leggi σ\sigma, scrivi ρ\rho, muoviti in direzione DD e passa a qq.

  • Movimenti: ←\leftarrow sinistra, →\rightarrow destra, −- testina ferma.
  • Inizio del nastro: su ▹\triangleright riscrivi ▹\triangleright e vai a destra.
  • Funzioni: termina in hh e lascia il risultato sul nastro; con più nastri, il simulatore legge l'ultimo.
  • Decisione: termina in yes per accettare o in no per rifiutare.
  • Regole mancanti: scrivi «in tutti gli altri casi rigetta».
  • Più nastri: per ciascuno indica il simbolo letto, quello scritto e il movimento.

Nelle tabelle, bb è un bit qualsiasi, bˉ\bar b il suo opposto e σ\sigma un simbolo qualsiasi. Se riscrivi bb o σ\sigma, il simbolo resta invariato.

Dall’idea alla tabella: quattro passi

  1. Descrivi l'idea. Scrivi in due righe cosa farai, prima di scegliere gli stati.
  2. Assegna gli stati. Uno per ogni informazione da ricordare: un bit, un riporto, una fase del calcolo.
  3. Copri i casi limite. Controlla input vuoto, overflow e arrivo all'inizio del nastro.
  4. Simula un esempio. Usa un input piccolo e controlla ogni transizione.

Per leggere le simulazioni, guarda la cella tra parentesi quadre: è quella sotto la testina. Ogni riga mostra un passo. Puoi poi verificare la tua macchina sui casi di prova del laboratorio.

Il blocco da riusare: raggiungere l’ultima cifra

Molte operazioni binarie partono da destra. Per raggiungere l'ultima cifra, scorri tutti i bit; sulla prima cella vuota, torna indietro di una posizione.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)
ss▹\triangleright(s,▹,→)(s, \triangleright, \rightarrow)
ssbb(s,b,→)(s, b, \rightarrow)
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow): da qui cambia da macchina a macchina

Le prime due righe sono sottintese nelle tabelle delle operazioni che usano questo blocco. Lo stato di arrivo sull’ultima riga dipende dall’esercizio.

Esempio guidato: l'incremento di 1

Costruisci la tabella in quattro passi. Le righe aggiunte a ogni passo sono evidenziate; alla fine puoi eseguire la macchina.

Aggiungere 1 a un numero binario. Parti da destra: trasforma ogni 1 finale in 0, poi cambia il primo 0 in 1. Per raggiungere l'ultima cifra, la macchina scorre l'input fino alla prima cella vuota e torna indietro di una posizione. Queste prime tre righe fanno proprio questo.

Transizioni scritte finora

  • δ(s, ▷) = (s, ▷, →)supera l'inizio del nastro
  • δ(s, b) = (s, b, →)vai in fondo
  • δ(s, ⊔) = (q, ⊔, ←)fine input, inizia il riporto

Come scrivere le transizioni

Scrivi una transizione per riga. Per esempio, q 1 -> q 0 L significa: «se sei in q e leggi 1, scrivi 0, spostati a sinistra e resta in q». In formule: δ(q,1)=(q,0,←)\delta(q, 1) = (q, 0, \leftarrow).

  • Movimenti: R = destra, L = sinistra, S = testina ferma.
  • Celle speciali: ▷ (oppure >) segna l'inizio del nastro; ⊔ (oppure _) indica una cella vuota.
  • Jolly: b indica un bit; b' un altro bit indipendente; b̄ (oppure !b) il bit opposto a b. σ (oppure *) indica un simbolo qualsiasi tranne ▷. A destra della freccia, b, b' e σ riscrivono il simbolo letto; b̄ scrive il bit opposto a b.
  • Stati finali: parti da s; termina in h per restituire un risultato, in yes per accettare o in no per rifiutare.
  • Commenti: usa #; il resto della riga non viene eseguito.

Con più nastri, scrivi a sinistra un simbolo letto per ciascun nastro. A destra, dopo il nuovo stato, scrivi una coppia «simbolo, movimento» per ciascuno. Esempio: s 0 ⊔ -> s 0 R 0 R.

Con un oracolo, scrivi la domanda sull'ultimo nastro ed entra in q?. La risposta porta la macchina in qYES oppure qNO.

Se manca una regola, la macchina rifiuta. Se più righe sono applicabili, hanno precedenza quelle con più simboli esatti. A parità di precedenza, ogni riga è un ramo nondeterministico.

Prova tu

Scegli un esercizio e completa le transizioni. Usa «Verifica i casi di prova» per confrontare i risultati con quelli attesi. Il programma si salva automaticamente in questo browser.

Nastro
▷1011⊔⊔⊔
Stato sPasso 0

Soluzioni delle tracce

Apri un esercizio per leggere il ragionamento, consultare la tabella ed eseguire la soluzione.

Incremento di 1funzione · 1 nastro

Nelle tracce: F14

Obiettivo. Aggiungere 1 al numero binario sul nastro.

Come procedere. Parti dall'ultima cifra e vai a sinistra: ogni 1 diventa 0; il primo 0 diventa 1 e il calcolo termina.

Caso limite. Se trovi solo 1, serve una cifra in più. Scrivi 1 all'inizio e aggiungi uno 0 in coda: 111+1=1000111 + 1 = 1000.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow)fine input, inizia il riporto
qq11(q,0,←)(q, 0, \leftarrow)1+riporto=01 + \text{riporto} = 0, il riporto continua
qq00(h,1,−)(h, 1, -)riporto assorbito, fine
qq▹\triangleright(o,▹,→)(o, \triangleright, \rightarrow)overflow
oo00(o′,1,→)(o', 1, \rightarrow)la prima cifra diventa 1
o′o'00(o′,0,→)(o', 0, \rightarrow)scorre le altre cifre
o′o'⊔\sqcup(h,0,−)(h, 0, -)aggiunge lo 0 in coda

Traccia su input 11 (= 3):

▷  1   1  [⊔]    s  : fine input, torno indietro
▷  1  [1]  ⊔     q  : 1 + riporto = 0, il riporto continua
▷ [1]  0   ⊔     q  : di nuovo 1 → 0
[▷] 0   0   ⊔     q  : sono all'inizio: overflow
▷ [0]  0   ⊔     o  : la prima cifra diventa 1
▷  1  [0]  ⊔     o' : scorro a destra
▷  1   0  [⊔]    o' : scrivo lo 0 finale e mi fermo
▷  1   0   0           risultato 100 = 4 ✔

🔎 La stessa traccia con le configurazioni

Una configurazione (q,w,u)(q, w, u) descrive un istante: qq è lo stato, ww è ciò che sta a sinistra della testina compreso il simbolo letto, uu è ciò che sta a destra. Per esempio (q,▹1,0⊔)(q, \triangleright 1, 0\sqcup) vuol dire: stato qq, la testina legge l'1, a destra ci sono 0⊔0\sqcup.

(s,▹,11)→∗(q,▹11,⊔)→(q,▹1,0⊔)→(q,▹,00⊔)→(o,▹0,0⊔)→(o′,▹10,⊔)→(o′,▹10⊔,ε)→(h,▹100,ε) (s, \triangleright, 11) \to^* (q, \triangleright 11, \sqcup) \to (q, \triangleright 1, 0\sqcup) \to (q, \triangleright, 00\sqcup) \to (o, \triangleright 0, 0\sqcup) \to (o', \triangleright 10, \sqcup) \to (o', \triangleright 10\sqcup, \varepsilon) \to (h, \triangleright 100, \varepsilon)

Il simbolo →∗\to^* vuol dire "in zero o più passi" (qui i passi di "vai in fondo"), e ε\varepsilon è la stringa vuota. Output: 100 ✔.

Nella tabella sono sottintese le righe del blocco «vai in fondo»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷1011⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ -> s ▷ R      # supera l'inizio del nastro
s b -> s b R      # vai in fondo
s ⊔ -> q ⊔ L      # fine input, inizia il riporto
q 1 -> q 0 L      # 1 + riporto = 0, il riporto continua
q 0 -> h 1 S      # riporto assorbito, fine
q ▷ -> o ▷ R      # overflow
o 0 -> o' 1 R     # la prima cifra diventa 1
o' 0 -> o' 0 R    # scorre le altre cifre
o' ⊔ -> h 0 S     # aggiunge lo 0 in coda
Moltiplicazione per 2funzione · 1 nastro

Nelle tracce: F13

Obiettivo. Moltiplicare per 2 il numero binario sul nastro.

Come procedere. Raggiungi la prima cella vuota, scrivi 0 e termina in hh. Aggiungere uno 0 a destra equivale a moltiplicare per 2: 101→1010101 \to 1010, cioè 5→105 \to 10.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)
ss⊔\sqcup(h,0,−)(h, 0, -)

Traccia su input 101 (= 5):

▷  1   0   1  [⊔]    s : fine input (dopo "vai in fondo"): scrivo 0 e mi fermo
▷  1   0   1  [0]    h : risultato 1010 = 10 = 2 · 5 ✔

Nella tabella sono sottintese le righe del blocco «vai in fondo»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷101⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ -> s ▷ R      # supera l'inizio del nastro
s b -> s b R      # vai in fondo
s ⊔ -> h 0 S      # fine input: scrive 0 e si ferma
Moltiplicazione per 4funzione · 1 nastro

Nelle tracce: G20v2

Obiettivo. Moltiplicare per 4 il numero binario sul nastro.

Come procedere. Raggiungi la fine dell'input e aggiungi due 0. Ogni 0 raddoppia il valore: 101→10100101 \to 10100, cioè 5⋅4=205 \cdot 4 = 20.

La testina parte su ▹\triangleright; la macchina termina in hh e lascia il risultato sul nastro. Nella tabella bb indica un bit qualsiasi e ⊔\sqcup una cella vuota.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss▹\triangleright(s,▹,→)(s, \triangleright, \rightarrow)supera l'inizio del nastro
ssbb(s,b,→)(s, b, \rightarrow)scorre l'input fino in fondo
ss⊔\sqcup(q,0,→)(q, 0, \rightarrow)fine input: scrive il primo 0
qq⊔\sqcup(h,0,−)(h, 0, -)scrive il secondo 0 e si ferma

Traccia su input 101 (= 5). Una riga per istante: tra parentesi quadre la cella sotto la testina, a destra lo stato e cosa fa la macchina.

▷  1   0   1  [⊔]  ⊔     s : fine input (dopo "vai in fondo"): scrivo 0 e vado a destra
▷  1   0   1   0  [⊔]    q : scrivo il secondo 0 e mi fermo
▷  1   0   1   0   0     h : risultato 10100 = 20 = 4 · 5 ✔

Caso limite. Con input 0 l'output è 000, che vale ancora 0 ✔: gli zeri a sinistra non cambiano il valore. La macchina è verificata con un simulatore su tutti gli input fino a 8 bit.

Prova la soluzione

Nastro
▷101⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ -> s ▷ R      # supera l'inizio del nastro
s b -> s b R      # vai in fondo
s ⊔ -> q 0 R      # fine input: scrive il primo 0
q ⊔ -> h 0 S      # scrive il secondo 0 e si ferma
Divisione intera per 2funzione · 1 nastro

Nelle tracce: F05, F07

Obiettivo. Calcolare la divisione intera per 2, scartando il resto.

Come procedere. Cancella l'ultima cifra: 101→10101 \to 10, cioè 5:2=25 : 2 = 2 con resto 1.

Caso limite. Se l'input ha una sola cifra, scrivi 0: il risultato non deve essere un nastro vuoto.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow)fine input
qqbb(r,⊔,←)(r, \sqcup, \leftarrow)cancella l'ultima cifra
rrbb(h,b,−)(h, b, -)è rimasta almeno una cifra
rr▹\triangleright(z,▹,→)(z, \triangleright, \rightarrow)non è rimasto niente…
zz⊔\sqcup(h,0,−)(h, 0, -)…quindi scrive 0

Traccia su input 101 (= 5) e sul caso limite 1:

▷  1   0   1  [⊔]    s : fine input, torno indietro
▷  1   0  [1]  ⊔     q : cancello l'ultima cifra
▷  1  [0]  ⊔   ⊔     r : è rimasta almeno una cifra: mi fermo (h)
                       risultato 10 = 2 ✔

▷  1  [⊔]            s : fine input, torno indietro
▷ [1]  ⊔             q : cancello l'unica cifra
[▷] ⊔   ⊔             r : non è rimasto niente
▷ [⊔]  ⊔             z : scrivo 0 e mi fermo (h)
                       risultato 0 ✔

Nella tabella sono sottintese le righe del blocco «vai in fondo»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷101⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ -> s ▷ R      # supera l'inizio del nastro
s b -> s b R      # vai in fondo
s ⊔ -> q ⊔ L      # fine input
q b -> r ⊔ L      # cancella l'ultima cifra
r b -> h b S      # è rimasta almeno una cifra
r ▷ -> z ▷ R      # non è rimasto niente…
z ⊔ -> h 0 S      # …quindi scrive 0
Divisione intera per 4funzione · 1 nastro

Nelle tracce: G20v5

Obiettivo. Calcolare la divisione intera per 4, scartando il resto.

Come procedere. Cancella le ultime due cifre: 10110→10110110 \to 101, cioè 22:4=522 : 4 = 5 con resto 2.

Caso limite. Se l'input ha una o due cifre, scrivi 0 invece di lasciare il nastro vuoto. La macchina termina in hh; bb indica un bit qualsiasi e ⊔\sqcup una cella vuota.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss▹\triangleright(s,▹,→)(s, \triangleright, \rightarrow)supera l'inizio del nastro
ssbb(s,b,→)(s, b, \rightarrow)scorre l'input fino in fondo
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow)fine input, torna sull'ultima cifra
qqbb(r,⊔,←)(r, \sqcup, \leftarrow)cancella l'ultima cifra
rrbb(t,⊔,←)(t, \sqcup, \leftarrow)cancella la penultima cifra
rr▹\triangleright(z,▹,→)(z, \triangleright, \rightarrow)l'input aveva una sola cifra
ttbb(h,b,−)(h, b, -)è rimasta almeno una cifra: fine
tt▹\triangleright(z,▹,→)(z, \triangleright, \rightarrow)non è rimasto niente…
zz⊔\sqcup(h,0,−)(h, 0, -)…quindi scrive 0

Traccia su input 10110 (= 22) e sul caso limite 11 (= 3). Una riga per istante: tra parentesi quadre la cella sotto la testina, a destra lo stato e cosa fa la macchina.

▷  1   0   1   1   0  [⊔]    s : fine input (dopo "vai in fondo"), torno indietro
▷  1   0   1   1  [0]  ⊔     q : cancello l'ultima cifra
▷  1   0   1  [1]  ⊔   ⊔     r : cancello la penultima cifra
▷  1   0  [1]  ⊔   ⊔   ⊔     t : è rimasta almeno una cifra: mi fermo (h)
                               risultato 101 = 5 = 22 : 4 (resto scartato) ✔

▷  1   1  [⊔]                s : fine input, torno indietro
▷  1  [1]  ⊔                 q : cancello l'ultima cifra
▷ [1]  ⊔   ⊔                 r : cancello la penultima cifra
[▷] ⊔   ⊔   ⊔                 t : non è rimasto niente
▷ [⊔]  ⊔   ⊔                 z : scrivo 0 e mi fermo (h)
                               risultato 0 = 3 : 4 ✔

Con input di una sola cifra (0 oppure 1) la macchina arriva su ▹\triangleright già nello stato rr e scrive 0 allo stesso modo. La macchina è verificata con un simulatore su tutti gli input fino a 8 bit.

Prova la soluzione

Nastro
▷10110⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ -> s ▷ R      # supera l'inizio del nastro
s b -> s b R      # vai in fondo
s ⊔ -> q ⊔ L      # fine input, torna sull'ultima cifra
q b -> r ⊔ L      # cancella l'ultima cifra
r b -> t ⊔ L      # cancella la penultima cifra
r ▷ -> z ▷ R      # l'input aveva una sola cifra
t b -> h b S      # è rimasta almeno una cifra: fine
t ▷ -> z ▷ R      # non è rimasto niente…
z ⊔ -> h 0 S      # …quindi scrive 0
Resto della divisione per 2funzione · 1 nastro

Nelle tracce: F02, F04, F06, G20v1

Obiettivo. Lasciare sul nastro solo il resto della divisione per 2: 0 oppure 1.

Come procedere. Leggi l'ultima cifra e ricordala nello stato c0c_0 o c1c_1. Cancella il numero tornando a sinistra, poi scrivi la cifra ricordata nella prima cella.

Nella tabella ii vale 0 o 1: le righe con cic_i e wiw_i descrivono entrambi i casi.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow)fine input
qq00(c0,⊔,←)(c_0, \sqcup, \leftarrow)ricorda 0
qq11(c1,⊔,←)(c_1, \sqcup, \leftarrow)ricorda 1
cic_ibb(ci,⊔,←)(c_i, \sqcup, \leftarrow)cancella le altre cifre
cic_i▹\triangleright(wi,▹,→)(w_i, \triangleright, \rightarrow)inizio del nastro
wiw_i⊔\sqcup(h,i,−)(h, i, -)scrive il resto

Traccia su input 101 (= 5):

▷  1   0   1  [⊔]    s  : fine input, torno indietro
▷  1   0  [1]  ⊔     q  : l'ultima cifra è 1: la ricordo (c1) e la cancello
▷  1  [0]  ⊔   ⊔     c1 : cancello
▷ [1]  ⊔   ⊔   ⊔     c1 : cancello
[▷] ⊔   ⊔   ⊔   ⊔     c1 : sono all'inizio
▷ [⊔]  ⊔   ⊔   ⊔     w1 : scrivo la cifra ricordata e mi fermo (h)
                        risultato 1 = resto di 5 diviso 2 ✔

Se il testo chiedesse invece una macchina di decisione ("accetta i numeri pari"), basterebbero le righe (q,0)→yes(q, 0) \to \text{yes} e (q,1)→no(q, 1) \to \text{no}.

Nella tabella sono sottintese le righe del blocco «vai in fondo»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷101⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ -> s ▷ R      # supera l'inizio del nastro
s b -> s b R      # vai in fondo
s ⊔ -> q ⊔ L      # fine input
q 0 -> c0 ⊔ L     # ricorda 0
q 1 -> c1 ⊔ L     # ricorda 1
c0 b -> c0 ⊔ L    # cancella le altre cifre
c1 b -> c1 ⊔ L
c0 ▷ -> w0 ▷ R    # inizio del nastro
c1 ▷ -> w1 ▷ R
w0 ⊔ -> h 0 S     # scrive il resto
w1 ⊔ -> h 1 S
Calcolare −x in complemento a duefunzione · 1 nastro

Nelle tracce: L18

Obiettivo. Calcolare −x-x in complemento a due, mantenendo lo stesso numero di bit.

Come procedere. Da destra, lascia invariati gli 0 finali e il primo 1. Poi inverti tutti i bit che restano a sinistra.

Perché funziona. È equivalente a invertire tutti i bit e sommare 1: il riporto ripristina gli 0 finali e il primo 1, mentre i bit a sinistra restano invertiti.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss⊔\sqcup(c,⊔,←)(c, \sqcup, \leftarrow)fine input
cc00(c,0,←)(c, 0, \leftarrow)copia gli 0 finali
cc11(i,1,←)(i, 1, \leftarrow)copia il primo 1, poi inverte
cc▹\triangleright(h,▹,→)(h, \triangleright, \rightarrow)x=0x = 0, quindi −x=0-x = 0
ii00(i,1,←)(i, 1, \leftarrow)inverte
ii11(i,0,←)(i, 0, \leftarrow)inverte
ii▹\triangleright(h,▹,→)(h, \triangleright, \rightarrow)fine

Traccia su input 0110 (= 6):

▷  0   1   1   0  [⊔]    s : fine input, torno indietro
▷  0   1   1  [0]  ⊔     c : 0 finale: lo copio
▷  0   1  [1]  0   ⊔     c : primo 1: lo copio, da qui inverto
▷  0  [1]  1   0   ⊔     i : 1 → 0
▷ [0]  0   1   0   ⊔     i : 0 → 1
[▷] 1   0   1   0   ⊔     i : sono all'inizio: mi fermo (h)
                           risultato 1010 = −6 ✔

Caso limite: per x=10…0x = 10\dots0 (il numero più negativo) la macchina restituisce xx stesso, perché −x-x non si può scrivere con lo stesso numero di bit.

Nella tabella sono sottintese le righe del blocco «vai in fondo»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷0110⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ -> s ▷ R      # supera l'inizio del nastro
s b -> s b R      # vai in fondo
s ⊔ -> c ⊔ L      # fine input
c 0 -> c 0 L      # copia gli 0 finali
c 1 -> i 1 L      # copia il primo 1, poi inverte
c ▷ -> h ▷ R      # x = 0, quindi −x = 0
i 0 -> i 1 L      # inverte
i 1 -> i 0 L
i ▷ -> h ▷ R      # fine
Interi positivi dispari in complemento a duedecisione · 1 nastro

Nelle tracce: F01

Obiettivo. Accettare solo gli interi positivi dispari scritti in complemento a due.

Come procedere. Controlla due condizioni: primo bit 0 (segno non negativo) e ultimo bit 1 (numero dispari, quindi diverso da zero). Per esempio, 011 è accettato; 111 è rifiutato perché negativo.

Qui devi leggere anche la prima cifra: non partire direttamente dal blocco «vai in fondo».

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss▹\triangleright(s,▹,→)(s, \triangleright, \rightarrow)
ss00(a,0,→)(a, 0, \rightarrow)segno positivo
ss11(no,1,−)(\text{no}, 1, -)negativo
ss⊔\sqcup(no,⊔,−)(\text{no}, \sqcup, -)stringa vuota
aabb(a,b,→)(a, b, \rightarrow)va in fondo
aa⊔\sqcup(t,⊔,←)(t, \sqcup, \leftarrow)torna sull'ultimo bit
tt11(yes,1,−)(\text{yes}, 1, -)dispari
tt00(no,0,−)(\text{no}, 0, -)pari (o zero)

Traccia su input 011 (= 3):

▷ [0]  1   1         s : primo bit 0, positivo
▷  0  [1]  1         a : vado in fondo
▷  0   1  [1]        a
▷  0   1   1  [⊔]    a : fine, torno sull'ultimo bit
▷  0   1  [1]  ⊔     t : ultimo bit 1, dispari: yes ✔

Con 110 (negativo) la macchina rigetta al primo bit; con 010 (pari) rigetta sull'ultimo.

Prova la soluzione

Nastro
▷011⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ -> s ▷ R
s 0 -> a 0 R      # segno positivo
s 1 -> no 1 S     # negativo
s ⊔ -> no ⊔ S     # stringa vuota
a b -> a b R      # va in fondo
a ⊔ -> t ⊔ L      # torna sull'ultimo bit
t 1 -> yes 1 S    # dispari
t 0 -> no 0 S     # pari (o zero)
Stringhe non palindrome: macchina nondeterministicadecisione · 2 nastri · nondeterministica

Nelle tracce: G20v4, FE23, MA23

Obiettivo. Accettare se esistono due cifre simmetriche diverse: xi≠xn+1−ix_i \neq x_{n+1-i}.

Come procedere, con 2 nastri.

  1. Scegli in modo nondeterministico una posizione ii dell'input.
  2. Per ogni cifra saltata scrivi una tacca I sul secondo nastro: ottieni i−1i-1 tacche.
  3. Ricorda nello stato la cifra scelta e raggiungi la fine dell'input.
  4. Torna indietro di una cella per ogni tacca e confronta la cifra raggiunta con quella ricordata.

Un ramo accetta quando trova una differenza. Basta un ramo accettante per riconoscere una stringa non palindroma.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssaa⊔\sqcupssa,→a, \rightarrowI,→I, \rightarrowscelta 1: salta la cifra aa
ssaa⊔\sqcupgag_aa,→a, \rightarrow⊔,−\sqcup, -scelta 2: confronta aa (ricordata nello stato)
ss⊔\sqcup⊔\sqcupno\text{no}⊔,−\sqcup, -⊔,−\sqcup, -nessuna cifra scelta
gag_abb⊔\sqcupgag_ab,→b, \rightarrow⊔,−\sqcup, -va in fondo
gag_a⊔\sqcup⊔\sqcupcac_a⊔,←\sqcup, \leftarrow⊔,←\sqcup, \leftarrowtorna indietro su entrambi
cac_abbIIcac_ab,←b, \leftarrowI,←I, \leftarrowconsuma una tacca per passo
cac_ab≠ab \neq a▹\trianglerightyes\text{yes}b,−b, -▹,→\triangleright, \rightarrowcifre simmetriche diverse
cac_ab=ab = a▹\trianglerightno\text{no}b,−b, -▹,→\triangleright, \rightarrowquesto ramo rigetta

Qui a∈{0,1}a \in \{0, 1\}, quindi gag_a e cac_a sono in realtà 2 + 2 stati. La macchina accetta xx se almeno un ramo accetta, cioè se esiste una coppia di cifre simmetriche diverse; se xx è palindroma, tutti i rami rigettano.

Il tempo. Il ramo che sceglie la posizione ii fa n+i+2n + i + 2 passi: ii per arrivare alla cifra scelta, n−in - i per arrivare in fondo, i−1i - 1 per tornare indietro consumando le tacche, più qualche passo di servizio. Quindi ogni ramo si ferma entro 2n+22n + 2 passi: è il "tempo 2n2n" della traccia, a meno di costanti che non contano (speedup lineare).

🔎 Traccia passo passo del ramo che sceglie i = 3 su x = 100

stato  nastro 1          nastro 2
s      [▷] 1  0  0       [▷]           parto
s       ▷ [1] 0  0        ▷ [⊔]         scelta 1: salto la cifra, scrivo una tacca
s       ▷  1 [0] 0        ▷  I [⊔]      scelta 1: salto, seconda tacca
s       ▷  1  0 [0]       ▷  I  I [⊔]   scelta 2: confronto questa (a = 0)
g0      ▷  1  0  0 [⊔]    ▷  I  I [⊔]   in fondo: torno indietro su entrambi
c0      ▷  1  0 [0] ⊔     ▷  I [I] ⊔    consumo una tacca
c0      ▷  1 [0] 0  ⊔     ▷ [I] I  ⊔    consumo una tacca
c0      ▷ [1] 0  0  ⊔    [▷] I  I  ⊔    tacche finite: sono su x1 = 1, diverso da a = 0
yes

Il ramo che sceglie i=1i = 1 non scrive tacche: dal fondo torna indietro di una sola cella, si trova su x3=0x_3 = 0, lo confronta con a=x1=1a = x_1 = 1 e accetta anche lui. Il ramo i=2i = 2 confronta la cifra centrale con se stessa e rigetta.

Prova la soluzione

Nastro 1
▷100⊔⊔⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R
s 0 ⊔ -> s 0 R I R      # scelta 1: salta la cifra 0
s 0 ⊔ -> g0 0 R ⊔ S     # scelta 2: confronta la cifra 0
s 1 ⊔ -> s 1 R I R      # scelta 1: salta la cifra 1
s 1 ⊔ -> g1 1 R ⊔ S     # scelta 2: confronta la cifra 1
s ⊔ ⊔ -> no ⊔ S ⊔ S     # nessuna cifra scelta
g0 b ⊔ -> g0 b R ⊔ S    # va in fondo
g1 b ⊔ -> g1 b R ⊔ S
g0 ⊔ ⊔ -> c0 ⊔ L ⊔ L    # torna indietro su entrambi
g1 ⊔ ⊔ -> c1 ⊔ L ⊔ L
c0 b I -> c0 b L I L    # consuma una tacca per passo
c1 b I -> c1 b L I L
c0 1 ▷ -> yes 1 S ▷ R   # cifre simmetriche diverse
c1 0 ▷ -> yes 0 S ▷ R
c0 0 ▷ -> no 0 S ▷ R    # questo ramo rigetta
c1 1 ▷ -> no 1 S ▷ R
Palindrome: macchina nondeterministica a 2 nastridecisione · 2 nastri · nondeterministica

Nelle tracce: F03

Obiettivo. Riconoscere una stringa palindroma con una macchina nondeterministica a 2 nastri.

Come procedere.

  1. Copia l'inizio dell'input sul secondo nastro e indovina dove termina la prima metà.
  2. Se la lunghezza è dispari, salta il bit centrale; se è pari, non saltare nulla.
  3. Confronta il resto dell'input con la copia letta all'indietro.

Un ramo accetta se tutti i confronti coincidono e le due metà finiscono insieme: ⊔\sqcup sul primo nastro, ▹\triangleright sul secondo.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssbb⊔\sqcupssb,→b, \rightarrowb,→b, \rightarrowscelta 1: copia bb, la prima metà continua
ssbb⊔\sqcupmmb,→b, \rightarrow⊔,←\sqcup, \leftarrowscelta 2: bb è il centro (lunghezza dispari), lo salta
ssbb⊔\sqcupmmb,−b, -⊔,←\sqcup, \leftarrowscelta 3: la prima metà finisce prima di bb (lunghezza pari)
ss⊔\sqcup⊔\sqcupmm⊔,−\sqcup, -⊔,←\sqcup, \leftarrowfine dell'input senza scelte: accetta solo la stringa vuota
mmbbbbmmb,→b, \rightarrowb,←b, \leftarrowcifre simmetriche uguali
mm⊔\sqcup▹\trianglerightyes\text{yes}⊔,−\sqcup, -▹,→\triangleright, \rightarrowfinite insieme: palindroma

In tutti gli altri casi rigetta: due cifre diverse, oppure un nastro finisce prima dell'altro (il punto scelto non era la metà). bb è un bit qualsiasi, riscritto uguale.

La macchina accetta se almeno un ramo accetta. Se xx è palindroma accetta il ramo che sceglie la metà giusta; se non lo è, ogni ramo trova due cifre diverse o finisce i nastri in momenti diversi, e rigetta. Ogni ramo si ferma entro n+3n + 3 passi; la macchina deterministica del file (sotto) ne fa 3n+43n + 4. Verificata con un simulatore su tutte le stringhe fino a 10 bit.

🔎 Traccia passo passo: il ramo che accetta su x = 101 e su x = 0110

stato  nastro 1             nastro 2
s      [▷] 1  0  1  ⊔      [▷] ⊔  ⊔
s       ▷ [1] 0  1  ⊔       ▷ [⊔] ⊔      scelta 1: copio 1
s       ▷  1 [0] 1  ⊔       ▷  1 [⊔]     scelta 2: 0 è il centro, lo salto
m       ▷  1  0 [1] ⊔       ▷ [1] ⊔      1 = 1
m       ▷  1  0  1 [⊔]     [▷] 1  ⊔      finiti insieme
yes

s      [▷] 0  1  1  0  ⊔   [▷] ⊔  ⊔
s       ▷ [0] 1  1  0  ⊔    ▷ [⊔] ⊔      scelta 1: copio 0
s       ▷  0 [1] 1  0  ⊔    ▷  0 [⊔]     scelta 1: copio 1
s       ▷  0  1 [1] 0  ⊔    ▷  0  1 [⊔]  scelta 3: la metà finisce qui
m       ▷  0  1 [1] 0  ⊔    ▷  0 [1] ⊔   1 = 1
m       ▷  0  1  1 [0] ⊔    ▷ [0] 1  ⊔   0 = 0
m       ▷  0  1  1  0 [⊔]  [▷] 0  1  ⊔   finiti insieme
yes

Gli altri rami rigettano. Su 101, per esempio, il ramo che sceglie la scelta 3 davanti allo 0 confronta 0 con 1; quello che copia tutte e tre le cifre arriva a ⊔\sqcup e trova sul 2° nastro una cifra invece di ▹\triangleright.

La soluzione del file è una MdT deterministica a 2 nastri (copia l'input, riavvolge il 1° nastro, confronta). Va bene anche quella, perché una MdT deterministica è un caso particolare di nondeterministica (ogni configurazione ha una sola mossa): è la palindrome deterministica.

Prova la soluzione

Nastro 1
▷101⊔⊔⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R
s b ⊔ -> s b R b R      # scelta 1: copia b, la prima metà continua
s b ⊔ -> m b R ⊔ L      # scelta 2: b è il centro (lunghezza dispari), lo salta
s b ⊔ -> m b S ⊔ L      # scelta 3: la prima metà finisce prima di b (lunghezza pari)
s ⊔ ⊔ -> m ⊔ S ⊔ L      # fine dell'input senza scelte
m b b -> m b R b L      # cifre simmetriche uguali
m ⊔ ▷ -> yes ⊔ S ▷ R    # finite insieme: palindroma
Palindrome: macchina deterministica a 2 nastridecisione · 2 nastri

Nelle tracce: F12, G17

Obiettivo. Riconoscere una stringa che si legge nello stesso modo da sinistra e da destra.

Come procedere, con 2 nastri.

  1. Copia l'intero input sul secondo nastro: stato ss.
  2. Riporta la prima testina all'inizio e lascia la seconda in fondo alla copia: stato rr.
  3. Confronta l'originale da sinistra con la copia da destra: stato cc.

Alla prima differenza rifiuta. Se tutti i bit coincidono e le due letture terminano insieme, accetta.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssbb⊔\sqcupssb,→b, \rightarrowb,→b, \rightarrowcopia l'input
ss⊔\sqcup⊔\sqcuprr⊔,←\sqcup, \leftarrow⊔,−\sqcup, -fine dell'input: la testina 2 resta dopo la copia
rrbb⊔\sqcuprrb,←b, \leftarrow⊔,−\sqcup, -riavvolge il 1° nastro
rr▹\triangleright⊔\sqcupcc▹,→\triangleright, \rightarrow⊔,←\sqcup, \leftarrowtestina 1 sulla prima cifra, testina 2 sull'ultima
ccbbbbccb,→b, \rightarrowb,←b, \leftarrowcifre simmetriche uguali
ccbbbˉ\bar bno\text{no}b,−b, -bˉ,−\bar b, -cifre simmetriche diverse
cc⊔\sqcup▹\trianglerightyes\text{yes}⊔,−\sqcup, -▹,→\triangleright, \rightarrowfinite insieme: palindroma

In tutti gli altri casi rigetta. bb è un bit qualsiasi, riscritto uguale, e bˉ\bar b il bit opposto. È la macchina della soluzione del file, ricontrollata: fa 3n+43n + 4 passi (copia, riavvolgimento, confronto) e accetta anche la stringa vuota. Verificata con un simulatore su tutte le stringhe fino a 10 bit.

🔎 Traccia passo passo su x = 010 (accetta) e su x = 011 (rigetta)

stato  nastro 1             nastro 2
s      [▷] 0  1  0  ⊔      [▷] ⊔  ⊔  ⊔  ⊔
s       ▷ [0] 1  0  ⊔       ▷ [⊔] ⊔  ⊔  ⊔    copio 0
s       ▷  0 [1] 0  ⊔       ▷  0 [⊔] ⊔  ⊔    copio 1
s       ▷  0  1 [0] ⊔       ▷  0  1 [⊔] ⊔    copio 0
s       ▷  0  1  0 [⊔]      ▷  0  1  0 [⊔]   fine dell'input
r       ▷  0  1 [0] ⊔       ▷  0  1  0 [⊔]   riavvolgo il nastro 1
r       ▷  0 [1] 0  ⊔       ▷  0  1  0 [⊔]
r       ▷ [0] 1  0  ⊔       ▷  0  1  0 [⊔]
r      [▷] 0  1  0  ⊔       ▷  0  1  0 [⊔]   inizio del nastro 1
c       ▷ [0] 1  0  ⊔       ▷  0  1 [0] ⊔    0 = 0
c       ▷  0 [1] 0  ⊔       ▷  0 [1] 0  ⊔    1 = 1
c       ▷  0  1 [0] ⊔       ▷ [0] 1  0  ⊔    0 = 0
c       ▷  0  1  0 [⊔]     [▷] 0  1  0  ⊔    finiti insieme
yes

Su 011 i primi nove passi sono uguali; al primo confronto la testina 1 legge 0 e la testina 2 legge l'ultima cifra, 1: diverse, quindi no.

🔎 Con il nondeterminismo si fa in tempo n

La macchina nondeterministica indovina dove finisce la prima metà e non deve riavvolgere: ogni ramo si ferma entro n+3n + 3 passi invece di 3n+43n + 4.

Prova la soluzione

Nastro 1
▷010⊔⊔⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R
s b ⊔ -> s b R b R      # copia l'input
s ⊔ ⊔ -> r ⊔ L ⊔ S      # fine dell'input: la testina 2 resta dopo la copia
r b ⊔ -> r b L ⊔ S      # riavvolge il 1° nastro
r ▷ ⊔ -> c ▷ R ⊔ L      # testina 1 sulla prima cifra, testina 2 sull'ultima
c b b -> c b R b L      # cifre simmetriche uguali
c b b̄ -> no b S b̄ S     # cifre simmetriche diverse
c ⊔ ▷ -> yes ⊔ S ▷ R    # finite insieme: palindroma
Confronto tra numeri binari: x ≤ ydecisione · 2 nastri

Nelle tracce: G20v3, MZ22, GE23

Obiettivo. Accettare l'input x;y se i due numeri binari hanno la stessa lunghezza e x≤yx \le y.

Come procedere, con 2 nastri. Copia xx sul secondo nastro, riporta la testina all'inizio e confronta xx e yy da sinistra. La prima coppia di bit diversi decide quale numero è maggiore.

Lo stato ee significa «finora uguali»; ll significa «xx è già minore». Le testine devono arrivare alla fine dei due numeri insieme: lunghezze diverse portano al rifiuto.

Statoletto₁ (yy)letto₂ (xx)nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssbb⊔\sqcupssb,→b, \rightarrowb,→b, \rightarrowcopia xx
ss;;⊔\sqcuprr;,→;, \rightarrow⊔,←\sqcup, \leftarrowtestina 1 sulla prima cifra di yy
rrσ\sigmabbrrσ,−\sigma, -b,←b, \leftarrowriavvolge il 2° nastro
rrσ\sigma▹\trianglerighteeσ,−\sigma, -▹,→\triangleright, \rightarrowpronto a confrontare
eebbbbeeb,→b, \rightarrowb,→b, \rightarrowcifre uguali
ee1100ll1,→1, \rightarrow0,→0, \rightarrowxx minore di yy
ee0011no\text{no}0,−0, -1,−1, -xx maggiore di yy
llbbb′b'llb,→b, \rightarrowb′,→b', \rightarrowormai conta solo la lunghezza (b′b' è un altro bit qualsiasi)
ee o ll⊔\sqcup⊔\sqcupyes\text{yes}⊔,−\sqcup, -⊔,−\sqcup, -stessa lunghezza e x≤yx \le y
ee o llbb⊔\sqcupno\text{no}——yy più lungo
ee o ll⊔\sqcupbbno\text{no}——xx più lungo

In tutti gli altri casi (per esempio se manca il ";") rigetta.

🔎 Traccia passo passo su 01;10

stato  nastro 1 (x;y)          nastro 2
s      [▷] 0  1  ;  1  0       [▷]
s       ▷ [0] 1  ;  1  0        ▷ [⊔]          copio x
s       ▷  0 [1] ;  1  0        ▷  0 [⊔]       copio x
s       ▷  0  1 [;] 1  0        ▷  0  1 [⊔]    fine di x
r       ▷  0  1  ; [1] 0        ▷  0 [1] ⊔     riavvolgo il nastro 2
r       ▷  0  1  ; [1] 0        ▷ [0] 1  ⊔
r       ▷  0  1  ; [1] 0       [▷] 0  1  ⊔     inizio del nastro 2
e       ▷  0  1  ; [1] 0        ▷ [0] 1  ⊔     y ha 1, x ha 0: x < y
l       ▷  0  1  ;  1 [0]       ▷  0 [1] ⊔     ormai conta solo la lunghezza
l       ▷  0  1  ;  1  0 [⊔]    ▷  0  1 [⊔]    finiscono insieme
yes

Prova la soluzione

Nastro 1
▷01;10⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R
s b ⊔ -> s b R b R      # copia x
s ; ⊔ -> r ; R ⊔ L      # testina 1 sulla prima cifra di y
r σ b -> r σ S b L      # riavvolge il 2° nastro
r σ ▷ -> e σ S ▷ R      # pronto a confrontare
e b b -> e b R b R      # cifre uguali
e 1 0 -> l 1 R 0 R      # x minore di y
e 0 1 -> no 0 S 1 S     # x maggiore di y
l b b' -> l b R b' R    # ormai conta solo la lunghezza
e ⊔ ⊔ -> yes ⊔ S ⊔ S    # stessa lunghezza e x ≤ y
l ⊔ ⊔ -> yes ⊔ S ⊔ S
e b ⊔ -> no b S ⊔ S     # y più lungo
l b ⊔ -> no b S ⊔ S
e ⊔ b -> no ⊔ S b S     # x più lungo
l ⊔ b -> no ⊔ S b S
Somma binaria senza overflowfunzione · 2 nastri

Nelle tracce: LU22

Obiettivo. Sommare i numeri binari dell'input x;y. Devono avere la stessa lunghezza e il risultato deve stare nello stesso numero di bit: 01+10=1101+10=11 è valido; 11+01=10011+01=100 causa overflow.

Come procedere, con 2 nastri.

  1. Copia xx sul secondo nastro e porta entrambe le testine sulle ultime cifre di xx e yy.
  2. Somma da destra verso sinistra, scrivendo il risultato sul secondo nastro.
  3. Usa c0c_0 per «nessun riporto» e c1c_1 per «riporto 1».

Le testine devono raggiungere insieme ; sul primo nastro e ▹\triangleright sul secondo. Se le lunghezze sono diverse o resta un riporto, rifiuta; altrimenti termina in hh con la somma sul secondo nastro.

Regola della somma. Con cifre a,ba,b e riporto rr, scrivi (a+b+r) mod 2(a+b+r)\bmod2 e porta 1 se a+b+r≥2a+b+r\ge2. Per esempio, 1+1+0=101+1+0=10: scrivi 0 e porta 1.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssbb⊔\sqcupssb,→b, \rightarrowb,→b, \rightarrowcopia xx
ss;;⊔\sqcupmm;,→;, \rightarrow⊔,−\sqcup, -xx copiato: la testina 2 aspetta qui
mmbb⊔\sqcupmmb,→b, \rightarrow⊔,−\sqcup, -scorre yy
mm⊔\sqcup⊔\sqcupc0c_0⊔,←\sqcup, \leftarrow⊔,←\sqcup, \leftarrowfine di yy: entrambe sull'ultima cifra
c0c_00000c0c_00,←0, \leftarrow0,←0, \leftarrow0+0=00 + 0 = 0
c0c_00011c0c_00,←0, \leftarrow1,←1, \leftarrow0+1=10 + 1 = 1
c0c_01100c0c_01,←1, \leftarrow1,←1, \leftarrow1+0=11 + 0 = 1
c0c_01111c1c_11,←1, \leftarrow0,←0, \leftarrow1+1=101 + 1 = 10: scrive 0, riporto 1
c1c_10000c0c_00,←0, \leftarrow1,←1, \leftarrow0+0+1=10 + 0 + 1 = 1: il riporto si esaurisce
c1c_10011c1c_10,←0, \leftarrow0,←0, \leftarrow0+1+1=100 + 1 + 1 = 10
c1c_11100c1c_11,←1, \leftarrow0,←0, \leftarrow1+0+1=101 + 0 + 1 = 10
c1c_11111c1c_11,←1, \leftarrow1,←1, \leftarrow1+1+1=111 + 1 + 1 = 11: scrive 1, riporto 1
c0c_0;;▹\trianglerighthh;,−;, -▹,→\triangleright, \rightarrowstessa lunghezza, nessun riporto: x+yx + y è sul 2° nastro
c1c_1;;▹\trianglerightno\text{no}——overflow
c0c_0 o c1c_1;;bbno\text{no}——xx più lungo
c0c_0 o c1c_1bb▹\trianglerightno\text{no}——yy più lungo

In tutti gli altri casi (per esempio se manca ";" o compare un simbolo diverso da 0 e 1) rigetta. La macchina è verificata con un simulatore su tutte le coppie x;yx;y fino a 5 bit ciascuno.

🔎 Traccia passo passo su 01;10 (1 + 2 = 3)

stato  nastro 1 (x;y)          nastro 2
s      [▷] 0  1  ;  1  0       [▷]
s       ▷ [0] 1  ;  1  0        ▷ [⊔]          copio x
s       ▷  0 [1] ;  1  0        ▷  0 [⊔]       copio x
s       ▷  0  1 [;] 1  0        ▷  0  1 [⊔]    fine di x
m       ▷  0  1  ; [1] 0        ▷  0  1 [⊔]    scorro y, la testina 2 aspetta
m       ▷  0  1  ;  1 [0]       ▷  0  1 [⊔]
m       ▷  0  1  ;  1  0 [⊔]    ▷  0  1 [⊔]    fine di y
c0      ▷  0  1  ;  1 [0]       ▷  0 [1] ⊔     0 + 1 = 1: scrivo 1
c0      ▷  0  1  ; [1] 0        ▷ [0] 1  ⊔     1 + 0 = 1: scrivo 1
c0      ▷  0  1 [;] 1  0       [▷] 1  1  ⊔     arrivano insieme, nessun riporto
h       sul nastro 2 resta 11

🔎 Traccia con overflow su 11;01 (3 + 1 = 4, che non sta in 2 cifre)

stato  nastro 1 (x;y)          nastro 2
...    (copia di x e scorrimento di y come sopra)
c0      ▷  1  1  ;  0 [1]       ▷  1 [1] ⊔     1 + 1 = 10: scrivo 0, riporto 1
c1      ▷  1  1  ; [0] 1        ▷ [1] 0  ⊔     0 + 1 + 1 = 10: scrivo 0, riporto 1
c1      ▷  1  1 [;] 0  1       [▷] 0  0  ⊔     arrivano insieme, ma con riporto
no      overflow

🔁 La tabella nel file della soluzione non funziona. Ha tre errori: la prima riga, δ(s,▹,▹)\delta(s, \triangleright, \triangleright), porta subito nello stato del riporto invece di restare in ss, quindi la macchina rigetta tutto; con il riporto, 0+0+10 + 0 + 1 dovrebbe togliere il riporto (tornare allo stato senza riporto) e 1+1+11 + 1 + 1 dovrebbe scrivere 1, non 0; alla fine la testina 1 legge ";", non ▹\triangleright, quindi le righe finali con (▹,▹)(\triangleright, \triangleright) non scattano mai. Inoltre una macchina che calcola una funzione termina in hh, non in yes.

Prova la soluzione

Nastro 1
▷01;10⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R
s b ⊔ -> s b R b R      # copia x
s ; ⊔ -> m ; R ⊔ S      # x copiato: la testina 2 aspetta qui
m b ⊔ -> m b R ⊔ S      # scorre y
m ⊔ ⊔ -> c0 ⊔ L ⊔ L     # fine di y: entrambe sull'ultima cifra
c0 0 0 -> c0 0 L 0 L    # 0 + 0 = 0
c0 0 1 -> c0 0 L 1 L    # 0 + 1 = 1
c0 1 0 -> c0 1 L 1 L    # 1 + 0 = 1
c0 1 1 -> c1 1 L 0 L    # 1 + 1 = 10: scrive 0, riporto 1
c1 0 0 -> c0 0 L 1 L    # 0 + 0 + 1 = 1: il riporto si esaurisce
c1 0 1 -> c1 0 L 0 L    # 0 + 1 + 1 = 10
c1 1 0 -> c1 1 L 0 L    # 1 + 0 + 1 = 10
c1 1 1 -> c1 1 L 1 L    # 1 + 1 + 1 = 11: scrive 1, riporto 1
c0 ; ▷ -> h ; S ▷ R     # stessa lunghezza, nessun riporto: x + y è sul 2° nastro
c1 ; ▷ -> no ; S ▷ S    # overflow
c0 ; b -> no ; S b S    # x più lungo
c1 ; b -> no ; S b S
c0 b ▷ -> no b S ▷ S    # y più lungo
c1 b ▷ -> no b S ▷ S
Chiave assente dalla listadecisione · 2 nastri

Nelle tracce: SE23, LU24

Obiettivo. Accettare se la chiave è diversa da tutti gli elementi della lista.

Input. Usa il formato key,el1,el2,…,eln,: la virgola è obbligatoria anche dopo l'ultimo elemento. Esempio: 01,1,011,.

Come procedere, con 2 nastri. Copia la chiave sul secondo nastro. Prima di ogni confronto, riporta la testina all'inizio della copia.

  • Se chiave ed elemento hanno gli stessi bit e finiscono insieme, rifiuta.
  • Se trovi bit diversi o lunghezze diverse, passa all'elemento successivo.
  • Se la lista finisce senza corrispondenze, accetta.
Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightcc▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ccbb⊔\sqcupccb,→b, \rightarrowb,→b, \rightarrowcopia key
cc,,⊔\sqcuprr,,→,, \rightarrow⊔,←\sqcup, \leftarrowfine di key
rrσ\sigmabbrrσ,−\sigma, -b,←b, \leftarrowriavvolge il 2° nastro
rrσ\sigma▹\trianglerightmmσ,−\sigma, -▹,→\triangleright, \rightarrowpronto a confrontare
mm⊔\sqcupqualsiasiyes\text{yes}——lista finita (dopo l'ultima virgola)
mmbbbbmmb,→b, \rightarrowb,→b, \rightarrowfinora uguali
mmbbbˉ\bar{b} oppure ⊔\sqcupkkb,→b, \rightarrow(uguale), −-cifre diverse, o elemento più lungo di key
mm,,bbrr,,→,, \rightarrowb,←b, \leftarrowelemento più corto: diverso
mm,,⊔\sqcupno\text{no}——elemento uguale a key
kkbbqualsiasikkb,→b, \rightarrow(uguale), −-salta il resto dell'elemento
kk,,qualsiasirr,,→,, \rightarrow(uguale), ←\leftarrowpassa al prossimo elemento

Nel formato della traccia la tabella è corretta (verificata con il simulatore).

🔎 Traccia passo passo su 01,00,01,

stato  nastro 1                       nastro 2
s      [▷] 0  1  ,  0  0  ,  0  1  ,  [▷]
c       ▷ [0] 1  ,  0  0  ,  0  1  ,   ▷ [⊔]         copio key
c       ▷  0 [1] ,  0  0  ,  0  1  ,   ▷  0 [⊔]
c       ▷  0  1 [,] 0  0  ,  0  1  ,   ▷  0  1 [⊔]   fine di key
r       ▷  0  1  , [0] 0  ,  0  1  ,   ▷  0 [1] ⊔    riavvolgo il nastro 2
r       ▷  0  1  , [0] 0  ,  0  1  ,   ▷ [0] 1  ⊔
r       ▷  0  1  , [0] 0  ,  0  1  ,  [▷] 0  1  ⊔
m       ▷  0  1  , [0] 0  ,  0  1  ,   ▷ [0] 1  ⊔    0 = 0
m       ▷  0  1  ,  0 [0] ,  0  1  ,   ▷  0 [1] ⊔    0 ≠ 1: elemento diverso
k       ▷  0  1  ,  0  0 [,] 0  1  ,   ▷  0 [1] ⊔    virgola: prossimo elemento
r       ▷  0  1  ,  0  0  , [0] 1  ,   ▷ [0] 1  ⊔    riavvolgo
r       ▷  0  1  ,  0  0  , [0] 1  ,  [▷] 0  1  ⊔
m       ▷  0  1  ,  0  0  , [0] 1  ,   ▷ [0] 1  ⊔    0 = 0
m       ▷  0  1  ,  0  0  ,  0 [1] ,   ▷  0 [1] ⊔    1 = 1
m       ▷  0  1  ,  0  0  ,  0  1 [,]  ▷  0  1 [⊔]   finiscono insieme: uguale a key
no

Con 01,1, invece: l'elemento 1 è diverso da 01 alla prima cifra, la macchina salta alla virgola, riavvolge, e all'inizio del nuovo elemento trova ⊔\sqcup: accetta.

🔎 Se mancasse l'ultima virgola: la variante

Su input senza la virgola finale, come 0,0, l'ultimo elemento finisce con ⊔\sqcup e la tabella sbaglia (accetta 0,0, rigetta 0,1). Per quel formato, al posto della riga "lista finita" servono tre righe:

  • (m,⊔,⊔)→no(m, \sqcup, \sqcup) \to \text{no}: l'ultimo elemento è uguale a key;
  • (m,⊔,b)→yes(m, \sqcup, b) \to \text{yes}: l'ultimo elemento è più corto, quindi diverso;
  • (k,⊔,qualsiasi)→yes(k, \sqcup, \text{qualsiasi}) \to \text{yes}: l'ultimo elemento era diverso.

All'esame vale la tabella principale, perché la traccia dice che la virgola finale fa parte dell'input; la variante, in quel formato, sbaglia con key vuota (rigetta ,0,).

Si assume l'input ben formato, come nelle soluzioni della dispensa. Per controllare anche il formato, aggiungi uno stato ii = "inizio di un elemento": rr va in ii invece che in mm, solo da ii il simbolo ⊔\sqcup porta a yes, e per il resto ii si comporta come mm. Così mm e kk su ⊔\sqcup rigettano (verificato con il simulatore).

Prova la soluzione

Nastro 1
▷01,00,01,⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ ▷ -> c ▷ R ▷ R
c b ⊔ -> c b R b R      # copia key
c , ⊔ -> r , R ⊔ L      # fine di key
r σ b -> r σ S b L      # riavvolge il 2° nastro
r σ ▷ -> m σ S ▷ R      # pronto a confrontare
m ⊔ σ -> yes ⊔ S σ S    # lista finita (dopo l'ultima virgola)
m b b -> m b R b R      # finora uguali
m b b̄ -> k b R b̄ S      # cifre diverse
m b ⊔ -> k b R ⊔ S      # elemento più lungo di key
m , b -> r , R b L      # elemento più corto: diverso
m , ⊔ -> no , S ⊔ S     # elemento uguale a key
k b σ -> k b R σ S      # salta il resto dell'elemento
k , σ -> r , R σ L      # passa al prossimo elemento
SAT-UNSAT con un oracolo SATdecisione · 2 nastri · oracolo SAT

Nelle tracce: F08, G16, E26, ND

Obiettivo. Accettare x;y se xx è soddisfacibile e yy non lo è.

L'oracolo SAT risponde in un passo alla domanda «questa formula è soddisfacibile?». La macchina scrive la formula sul secondo nastro ed entra in q?q_?; la risposta la porta in qYESq_{\text{YES}} o qNOq_{\text{NO}}, senza spostare le testine.

Come procedere.

  1. Copia xx sul nastro di query e interroga l'oracolo. Se risponde no, rifiuta.
  2. Se risponde sì, cancella la query e copia yy.
  3. Interroga di nuovo l'oracolo: accetta solo se questa volta risponde no.

Bastano due chiamate: SAT-UNSAT∈PSAT\mathrm{SAT\text{-}UNSAT} \in \mathrm{P}^{\mathrm{SAT}}. Nella tabella σ\sigma indica un simbolo della formula, esclusi ;, ⊔\sqcup e ▹\triangleright.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssσ\sigma⊔\sqcupssσ,→\sigma, \rightarrowσ,→\sigma, \rightarrowcopia xx
ss;;⊔\sqcupq?q_?;,−;, -⊔,−\sqcup, -"x∈SATx \in \mathrm{SAT}?"
qNOq_{\text{NO}};;⊔\sqcupno\text{no};,−;, -⊔,−\sqcup, -xx insoddisfacibile
qYESq_{\text{YES}};;⊔\sqcuprr;,−;, -⊔,←\sqcup, \leftarrowxx soddisfacibile: si passa a yy
rr;;σ\sigmarr;,−;, -⊔,←\sqcup, \leftarrowcancella la query
rr;;▹\trianglerightaa;,→;, \rightarrow▹,→\triangleright, \rightarrowquery cancellata
aaσ\sigma⊔\sqcupaaσ,→\sigma, \rightarrowσ,→\sigma, \rightarrowcopia yy
aa⊔\sqcup⊔\sqcupq?q_?⊔,−\sqcup, -⊔,−\sqcup, -"y∈SATy \in \mathrm{SAT}?"
qYESq_{\text{YES}}⊔\sqcup⊔\sqcupno\text{no}⊔,−\sqcup, -⊔,−\sqcup, -yy soddisfacibile
qNOq_{\text{NO}}⊔\sqcup⊔\sqcupyes\text{yes}⊔,−\sqcup, -⊔,−\sqcup, -xx sì, yy no

In tutti gli altri casi rigetta. È la tabella della dispensa, con σ\sigma al posto della sua xx per non confonderla con la formula xx. Le due chiamate si distinguono dal simbolo sul 1° nastro: dopo la prima la testina 1 è su ";", dopo la seconda è su ⊔\sqcup.

Traccia per fasi, con xx soddisfacibile e yy no:

fase                nastro 1 (input)     nastro 2 (query)    stato
copia x             ▷ x [;] y            ▷ x [⊔]             s → q?
1ª domanda          ▷ x [;] y            ▷ x [⊔]             q? → qYES  (x è soddisfacibile)
cancella la query   ▷ x [;] y           [▷] ⊔ ⊔              r → a
copia y             ▷ x ; y [⊔]          ▷ y [⊔]             a → q?
2ª domanda          ▷ x ; y [⊔]          ▷ y [⊔]             q? → qNO   (y non lo è)
fine                                                         yes

Da ricordare. Per la domanda 8 scrivi l'idea in due righe, poi la tabella δ\delta: uno stato per ogni cosa da ricordare, le righe per i casi limite (▹\triangleright, stringa vuota, overflow) e "in tutti gli altri casi rigetta". Sui numeri binari si lavora da destra, dopo il blocco "vai in fondo"; con più nastri si copia una parte dell'input sul 2° nastro e si confronta. Prima di consegnare, simula la macchina su un input piccolo, riga per riga.

Prova la soluzione

Nastro 1
▷(x|y)&!x;x&!x⊔⊔
Nastro 2 (query)
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R
s σ ⊔ -> s σ R σ R          # copia x
s ; ⊔ -> q? ; S ⊔ S         # "x ∈ SAT?"
s ⊔ ⊔ -> no ⊔ S ⊔ S         # manca ";" (qui σ non comprende ⊔)
qNO ; ⊔ -> no ; S ⊔ S       # x insoddisfacibile
qYES ; ⊔ -> r ; S ⊔ L       # x soddisfacibile: si passa a y
r ; σ -> r ; S ⊔ L          # cancella la query
r ; ▷ -> a ; R ▷ R          # query cancellata
a σ ⊔ -> a σ R σ R          # copia y
a ⊔ ⊔ -> q? ⊔ S ⊔ S         # "y ∈ SAT?"
qYES ⊔ ⊔ -> no ⊔ S ⊔ S      # y soddisfacibile
qNO ⊔ ⊔ -> yes ⊔ S ⊔ S      # x sì, y no
INDEPENDENT SET con un oracolo CLIQUEdecisione · 2 nastri · oracolo CLIQUE

Nelle tracce: SP

Obiettivo. Decidere se un grafo ha un insieme di almeno KK nodi senza archi tra loro, usando un oracolo CLIQUE.

Input. Scrivi la matrice di adiacenza con , tra gli elementi e ; tra le righe, poi : e KK in binario.

L'idea. Un insieme indipendente in GG è una cricca nel grafo complemento Gˉ\bar G: tra nodi distinti, c'è un arco dove prima non c'era.

Come procedere. Copia la matrice sul nastro di query invertendo 0 e 1. Copia KK senza modificarlo e interroga l'oracolo. Basta una domanda: «il complemento ha una cricca di almeno KK nodi?».

Esempio. Nel cammino 1–2–3, i nodi 1 e 3 non sono collegati. Nel complemento formano una cricca: con K=2K=2 l'oracolo risponde sì. Come spiegato sotto, la diagonale non influenza il test.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ss00⊔\sqcupss0,→0, \rightarrow1,→1, \rightarrowinverte il bit: c'è un arco in Gˉ\bar G
ss11⊔\sqcupss1,→1, \rightarrow0,→0, \rightarrowinverte il bit: niente arco in Gˉ\bar G
ss,,⊔\sqcupss,,→,, \rightarrow,,→,, \rightarrowcopia il separatore
ss;;⊔\sqcupss;,→;, \rightarrow;,→;, \rightarrowcopia il separatore
ss::⊔\sqcupkk:,→:, \rightarrow:,→:, \rightarrowfine della matrice
kkbb⊔\sqcupkkb,→b, \rightarrowb,→b, \rightarrowcopia KK senza cambiarlo
kk⊔\sqcup⊔\sqcupq?q_?⊔,−\sqcup, -⊔,−\sqcup, -"Gˉ\bar G ha una cricca di almeno KK nodi?"
qYESq_{\text{YES}}⊔\sqcup⊔\sqcupyes\text{yes}⊔,−\sqcup, -⊔,−\sqcup, -c'è un independent set di almeno KK nodi
qNOq_{\text{NO}}⊔\sqcup⊔\sqcupno\text{no}⊔,−\sqcup, -⊔,−\sqcup, -non c'è

In tutti gli altri casi (per esempio se manca ":") rigetta. La macchina è verificata con un simulatore, con un oracolo simulato, su tutti i grafi fino a 4 nodi e tutte le soglie da 0 a 5.

Traccia per fasi sull'esempio:

fase                 nastro 1 (input)                   nastro 2 (query)                    stato
inverte la matrice   ▷ 0,1,0;1,0,1;0,1,0 [:] 10         ▷ 1,0,1;0,1,0;1,0,1 [⊔]             s → k
copia K              ▷ 0,1,0;1,0,1;0,1,0:10 [⊔]         ▷ 1,0,1;0,1,0;1,0,1:10 [⊔]          k → q?
domanda              "il complemento ha una cricca di 2 nodi?" sì, {1, 3}                     q? → qYES
fine                                                                                           yes

🔎 E la diagonale della matrice?

Invertendo tutte le celle, anche la diagonale passa da 0 a 1, come se ogni nodo fosse collegato a sé stesso. Non cambia la risposta: una cricca chiede archi tra nodi distinti, quindi l'oracolo non guarda la diagonale (lo assumiamo, come è naturale). Lasciarla a 0 richiederebbe di contare riga e colonna con due contatori in binario: più stati, nessuna idea nuova.

Perché è polinomiale e cosa mostra. La macchina fa una passata sull'input e una sola domanda all'oracolo, quindi INDEPENDENT SET sta in PCLIQUE\mathrm{P}^{\mathrm{CLIQUE}}. Non sorprende: la traduzione "prendi il complemento del grafo" è la riduzione da INDEPENDENT SET a CLIQUE, e qui la macchina la calcola e passa il risultato all'oracolo.

Prova la soluzione

Nastro 1
▷0,1,0;1,0,1;0,1,0:10⊔⊔
Nastro 2 (query)
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R
s 0 ⊔ -> s 0 R 1 R      # inverte il bit: c'è un arco nel complemento
s 1 ⊔ -> s 1 R 0 R      # inverte il bit: niente arco nel complemento
s , ⊔ -> s , R , R      # copia il separatore
s ; ⊔ -> s ; R ; R
s : ⊔ -> k : R : R      # fine della matrice
k b ⊔ -> k b R b R      # copia K senza cambiarlo
k ⊔ ⊔ -> q? ⊔ S ⊔ S     # "il complemento ha una cricca di almeno K nodi?"
qYES ⊔ ⊔ -> yes ⊔ S ⊔ S # c'è un independent set di almeno K nodi
qNO ⊔ ⊔ -> no ⊔ S ⊔ S   # non c'è