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 è 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)
segna l'inizio del nastro; indica una cella vuota. La testina parte su , nello stato .
Come leggere una transizione
La macchina si descrive con : stati, alfabeto, transizioni e stato iniziale.
Una regola si legge così: nello stato , se leggi , scrivi , muoviti in direzione e passa a .
- Movimenti: sinistra, destra, testina ferma.
- Inizio del nastro: su riscrivi e vai a destra.
- Funzioni: termina in 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, è un bit qualsiasi, il suo opposto e un simbolo qualsiasi. Se riscrivi o , il simbolo resta invariato.
Dall’idea alla tabella: quattro passi
- Descrivi l'idea. Scrivi in due righe cosa farai, prima di scegliere gli stati.
- Assegna gli stati. Uno per ogni informazione da ricordare: un bit, un riporto, una fase del calcolo.
- Copri i casi limite. Controlla input vuoto, overflow e arrivo all'inizio del nastro.
- 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.
| : 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: .
- Movimenti:
R= destra,L= sinistra,S= testina ferma. - Celle speciali:
▷(oppure>) segna l'inizio del nastro;⊔(oppure_) indica una cella vuota. - Jolly:
bindica un bit;b'un altro bit indipendente;b̄(oppure!b) il bit opposto ab.σ(oppure*) indica un simbolo qualsiasi tranne▷. A destra della freccia,b,b'eσriscrivono il simbolo letto;b̄scrive il bit opposto ab. - Stati finali: parti da
s; termina inhper restituire un risultato, inyesper accettare o innoper 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.
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: .
| commento | |||
|---|---|---|---|
| fine input, inizia il riporto | |||
| , il riporto continua | |||
| riporto assorbito, fine | |||
| overflow | |||
| la prima cifra diventa 1 | |||
| scorre le altre cifre | |||
| 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 descrive un istante: è lo stato, è ciò che sta a sinistra della testina compreso il simbolo letto, è ciò che sta a destra. Per esempio vuol dire: stato , la testina legge l'1, a destra ci sono .
Il simbolo vuol dire "in zero o più passi" (qui i passi di "vai in fondo"), e è la stringa vuota. Output: 100 ✔.
Nella tabella sono sottintese le righe del blocco «vai in fondo»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
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 . Aggiungere uno 0 a destra equivale a moltiplicare per 2: , cioè .
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»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
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: , cioè .
La testina parte su ; la macchina termina in e lascia il risultato sul nastro. Nella tabella indica un bit qualsiasi e una cella vuota.
| commento | |||
|---|---|---|---|
| supera l'inizio del nastro | |||
| scorre l'input fino in fondo | |||
| fine input: scrive il primo 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
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
Obiettivo. Calcolare la divisione intera per 2, scartando il resto.
Come procedere. Cancella l'ultima cifra: , cioè con resto 1.
Caso limite. Se l'input ha una sola cifra, scrivi 0: il risultato non deve essere un nastro vuoto.
| commento | |||
|---|---|---|---|
| fine input | |||
| cancella l'ultima cifra | |||
| è rimasta almeno una cifra | |||
| non è rimasto niente… | |||
| …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»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
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: , cioè 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 ; indica un bit qualsiasi e una cella vuota.
| commento | |||
|---|---|---|---|
| supera l'inizio del nastro | |||
| scorre l'input fino in fondo | |||
| fine input, torna sull'ultima cifra | |||
| cancella l'ultima cifra | |||
| cancella la penultima cifra | |||
| l'input aveva una sola cifra | |||
| è rimasta almeno una cifra: fine | |||
| non è rimasto niente… | |||
| …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 già nello stato e scrive 0 allo stesso modo. La macchina è verificata con un simulatore su tutti gli input fino a 8 bit.
Prova la soluzione
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 o . Cancella il numero tornando a sinistra, poi scrivi la cifra ricordata nella prima cella.
Nella tabella vale 0 o 1: le righe con e descrivono entrambi i casi.
| commento | |||
|---|---|---|---|
| fine input | |||
| ricorda 0 | |||
| ricorda 1 | |||
| cancella le altre cifre | |||
| inizio del nastro | |||
| 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 e .
Nella tabella sono sottintese le righe del blocco «vai in fondo»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
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 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.
| commento | |||
|---|---|---|---|
| fine input | |||
| copia gli 0 finali | |||
| copia il primo 1, poi inverte | |||
| , quindi | |||
| inverte | |||
| inverte | |||
| 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 (il numero più negativo) la macchina restituisce stesso, perché non si può scrivere con lo stesso numero di bit.
Nella tabella sono sottintese le righe del blocco «vai in fondo»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
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».
| commento | |||
|---|---|---|---|
| segno positivo | |||
| negativo | |||
| stringa vuota | |||
| va in fondo | |||
| torna sull'ultimo bit | |||
| dispari | |||
| 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
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: .
Come procedere, con 2 nastri.
- Scegli in modo nondeterministico una posizione dell'input.
- Per ogni cifra saltata scrivi una tacca
Isul secondo nastro: ottieni tacche. - Ricorda nello stato la cifra scelta e raggiungi la fine dell'input.
- 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.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| scelta 1: salta la cifra | ||||||
| scelta 2: confronta (ricordata nello stato) | ||||||
| nessuna cifra scelta | ||||||
| va in fondo | ||||||
| torna indietro su entrambi | ||||||
| consuma una tacca per passo | ||||||
| cifre simmetriche diverse | ||||||
| questo ramo rigetta |
Qui , quindi e sono in realtà 2 + 2 stati. La macchina accetta se almeno un ramo accetta, cioè se esiste una coppia di cifre simmetriche diverse; se è palindroma, tutti i rami rigettano.
Il tempo. Il ramo che sceglie la posizione fa passi: per arrivare alla cifra scelta, per arrivare in fondo, per tornare indietro consumando le tacche, più qualche passo di servizio. Quindi ogni ramo si ferma entro passi: è il "tempo " 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 non scrive tacche: dal fondo torna indietro di una sola cella, si trova su , lo confronta con e accetta anche lui. Il ramo confronta la cifra centrale con se stessa e rigetta.
Prova la soluzione
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.
- Copia l'inizio dell'input sul secondo nastro e indovina dove termina la prima metà.
- Se la lunghezza è dispari, salta il bit centrale; se è pari, non saltare nulla.
- 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: sul primo nastro, sul secondo.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| scelta 1: copia , la prima metà continua | ||||||
| scelta 2: è il centro (lunghezza dispari), lo salta | ||||||
| scelta 3: la prima metà finisce prima di (lunghezza pari) | ||||||
| fine dell'input senza scelte: accetta solo la stringa vuota | ||||||
| cifre simmetriche uguali | ||||||
| finite 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à). è un bit qualsiasi, riscritto uguale.
La macchina accetta se almeno un ramo accetta. Se è 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 passi; la macchina deterministica del file (sotto) ne fa . 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 e trova sul 2° nastro una cifra invece di .
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
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
Obiettivo. Riconoscere una stringa che si legge nello stesso modo da sinistra e da destra.
Come procedere, con 2 nastri.
- Copia l'intero input sul secondo nastro: stato .
- Riporta la prima testina all'inizio e lascia la seconda in fondo alla copia: stato .
- Confronta l'originale da sinistra con la copia da destra: stato .
Alla prima differenza rifiuta. Se tutti i bit coincidono e le due letture terminano insieme, accetta.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia l'input | ||||||
| fine dell'input: la testina 2 resta dopo la copia | ||||||
| riavvolge il 1° nastro | ||||||
| testina 1 sulla prima cifra, testina 2 sull'ultima | ||||||
| cifre simmetriche uguali | ||||||
| cifre simmetriche diverse | ||||||
| finite insieme: palindroma |
In tutti gli altri casi rigetta. è un bit qualsiasi, riscritto uguale, e il bit opposto. È la macchina della soluzione del file, ricontrollata: fa 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 passi invece di .
Prova la soluzione
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 .
Come procedere, con 2 nastri. Copia sul secondo nastro, riporta la testina all'inizio e confronta e da sinistra. La prima coppia di bit diversi decide quale numero è maggiore.
Lo stato significa «finora uguali»; significa « è già minore». Le testine devono arrivare alla fine dei due numeri insieme: lunghezze diverse portano al rifiuto.
| Stato | letto₁ () | letto₂ () | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia | ||||||
| testina 1 sulla prima cifra di | ||||||
| riavvolge il 2° nastro | ||||||
| pronto a confrontare | ||||||
| cifre uguali | ||||||
| minore di | ||||||
| maggiore di | ||||||
| ormai conta solo la lunghezza ( è un altro bit qualsiasi) | ||||||
| o | stessa lunghezza e | |||||
| o | — | — | più lungo | |||
| o | — | — | 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
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: è valido; causa overflow.
Come procedere, con 2 nastri.
- Copia sul secondo nastro e porta entrambe le testine sulle ultime cifre di e .
- Somma da destra verso sinistra, scrivendo il risultato sul secondo nastro.
- Usa per «nessun riporto» e per «riporto 1».
Le testine devono raggiungere insieme ; sul primo nastro e sul secondo. Se le lunghezze sono diverse o resta un riporto, rifiuta; altrimenti termina in con la somma sul secondo nastro.
Regola della somma. Con cifre e riporto , scrivi e porta 1 se . Per esempio, : scrivi 0 e porta 1.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia | ||||||
| copiato: la testina 2 aspetta qui | ||||||
| scorre | ||||||
| fine di : entrambe sull'ultima cifra | ||||||
| : scrive 0, riporto 1 | ||||||
| : il riporto si esaurisce | ||||||
| : scrive 1, riporto 1 | ||||||
| stessa lunghezza, nessun riporto: è sul 2° nastro | ||||||
| — | — | overflow | ||||
| o | — | — | più lungo | |||
| o | — | — | 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 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, , porta subito nello stato del riporto invece di restare in , quindi la macchina rigetta tutto; con il riporto, dovrebbe togliere il riporto (tornare allo stato senza riporto) e dovrebbe scrivere 1, non 0; alla fine la testina 1 legge ";", non , quindi le righe finali con non scattano mai. Inoltre una macchina che calcola una funzione termina in , non in yes.
Prova la soluzione
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
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.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia key | ||||||
| fine di key | ||||||
| riavvolge il 2° nastro | ||||||
| pronto a confrontare | ||||||
| qualsiasi | — | — | lista finita (dopo l'ultima virgola) | |||
| finora uguali | ||||||
| oppure | (uguale), | cifre diverse, o elemento più lungo di key | ||||
| elemento più corto: diverso | ||||||
| — | — | elemento uguale a key | ||||
| qualsiasi | (uguale), | salta il resto dell'elemento | ||||
| qualsiasi | (uguale), | passa 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 : accetta.
🔎 Se mancasse l'ultima virgola: la variante
Su input senza la virgola finale, come 0,0, l'ultimo elemento finisce con e la tabella sbaglia (accetta 0,0, rigetta 0,1). Per quel formato, al posto della riga "lista finita" servono tre righe:
- : l'ultimo elemento è uguale a key;
- : l'ultimo elemento è più corto, quindi diverso;
- : 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 = "inizio di un elemento": va in invece che in , solo da il simbolo porta a yes, e per il resto si comporta come . Così e su rigettano (verificato con il simulatore).
Prova la soluzione
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 è soddisfacibile e 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 ; la risposta la porta in o , senza spostare le testine.
Come procedere.
- Copia sul nastro di query e interroga l'oracolo. Se risponde no, rifiuta.
- Se risponde sì, cancella la query e copia .
- Interroga di nuovo l'oracolo: accetta solo se questa volta risponde no.
Bastano due chiamate: . Nella tabella indica un simbolo della formula, esclusi ;, e .
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia | ||||||
| "?" | ||||||
| insoddisfacibile | ||||||
| soddisfacibile: si passa a | ||||||
| cancella la query | ||||||
| query cancellata | ||||||
| copia | ||||||
| "?" | ||||||
| soddisfacibile | ||||||
| sì, no |
In tutti gli altri casi rigetta. È la tabella della dispensa, con al posto della sua per non confonderla con la formula . Le due chiamate si distinguono dal simbolo sul 1° nastro: dopo la prima la testina 1 è su ";", dopo la seconda è su .
Traccia per fasi, con soddisfacibile e 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 : uno stato per ogni cosa da ricordare, le righe per i casi limite (, 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
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 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 in binario.
L'idea. Un insieme indipendente in è una cricca nel grafo complemento : 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 senza modificarlo e interroga l'oracolo. Basta una domanda: «il complemento ha una cricca di almeno nodi?».
Esempio. Nel cammino 1–2–3, i nodi 1 e 3 non sono collegati. Nel complemento formano una cricca: con l'oracolo risponde sì. Come spiegato sotto, la diagonale non influenza il test.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| inverte il bit: c'è un arco in | ||||||
| inverte il bit: niente arco in | ||||||
| copia il separatore | ||||||
| copia il separatore | ||||||
| fine della matrice | ||||||
| copia senza cambiarlo | ||||||
| " ha una cricca di almeno nodi?" | ||||||
| c'è un independent set di almeno nodi | ||||||
| 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 . 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
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'è