Questo è un ulteriore sviluppo della risposta di @ ais523 , riducendola a solo due serie di parentesi e usando anche un posizionamento cellulare più compatto basato sulla teoria del righello Golomb. ais523 ha creato un compilatore per questa costruzione , così come questa sessione TIO che mostra un programma BF risultante di esempio in esecuzione con traccia di debug dei contatori TWM.
Come l'originale, questo inizia con un programma in The Waterfall Model , con alcune restrizioni che non perdono la generalità:
- Tutti i contatori hanno lo stesso valore di auto-reset R ; vale a dire, la mappa di trigger TWM f ha la proprietà che f( x , x ) = R per tutti X .
- C'è un solo contatore di arresto h .
- Il numero c di contatori è (p−1)/2 per alcuni numeri primi p .
Righello Golomb
Combiniamo la costruzione Erdős – Turán con la funzione di permutazione di un array Welch – Costas per ottenere un righello Golomb con le proprietà necessarie.
(Sono sicuro che questa costruzione combinata non può essere una nuova idea ma abbiamo appena trovato e messo insieme questi due pezzi di Wikipedia.)
Sia r una radice primitiva di p=2c+1 . Definire la funzione
g(k)=4ck−((rk−1)mod(2c+1)),k=0,…,2c−1.
- g è un sovrano Golomb dell'ordine . Cioè, la differenza è unica per ogni coppia di numeri distinti .2 c g ( i ) - g ( j ) i , j ∈ { 0 , … , 2 c - 1 }2cg(i)−g(j)i,j∈{0,…,2c−1}
- g(k)mod(2c) assume ogni valore esattamente una volta.0,…,2c−1
Struttura a nastro
Per ogni contatore TWM , assegniamo due posizioni di cella nastro BF, una cella di fallback e una cella di valore :x∈{0,…,c−1}u ( x ) v ( x ) u(x) v(x)
u(x)=g(k1)<v(x)=g(k2) with u(x)≡v(x)≡x(modc)
Con la seconda proprietà di ci sono esattamente due distinti valori tra cui scegliere.gk1,k2
Il contenuto di una cella di fallback verrà mantenuto per lo più a , tranne quando il suo contatore è stato appena visitato, quando sarà a , il doppio del valore di auto-reset del contatore. Una cella di valore verrà mantenuta al doppio del valore del contatore TWM corrispondente.02R
Tutte le altre celle che possono essere raggiunte dall'esecuzione del programma BF (un numero finito) saranno mantenute a valori dispari, in modo che testino sempre come diverso da zero. Dopo l'inizializzazione, questo è automatico perché tutte le regolazioni delle celle sono pari.
Se lo si desidera, tutte le posizioni delle celle possono essere spostate a destra di una costante per evitare di spostarsi a sinistra della posizione iniziale del nastro BF.
Struttura del programma BF
Sia la distanza tra il valore del contatore di arresto e le celle di fallback, e sia un numero abbastanza grande che per tutti i contatori . Quindi la struttura di base del programma BF èH=v(h)−u(h)NcN+1≥v((x+1)modc)−u(x)x
inizializzazione regolazioni[
>
×(H+cN+1) [
<
×c × H]
<
×H ]
Inizializzazione
La fase di inizializzazione imposta tutte le celle raggiungibili dal programma sui loro valori iniziali, in uno stato come se l'ultimo contatore fosse stato appena visitato e la sola cella attiva fosse la sua cella di fallback :u(c−1)
- Le celle valore vengono inizializzate al doppio del contenuto iniziale del contatore TWM corrispondente, tranne per il fatto che il contatore è pre-decrementato.0
- Le celle di fallback sono impostate su , tranne la cella , che è impostata su .0u(c−1)2R
- Tutte le altre celle raggiungibili dal programma (un numero finito) sono impostati a .1
Quindi il puntatore del nastro viene spostato in posizione (una cella sempre diversa da zero) prima di raggiungere il primo programma .u(c−1)−H[
Inizio del ciclo esterno
All'inizio di un'iterazione del ciclo esterno, il puntatore del nastro sarà su oppure per un contatore .u(x)−Hv(x)−Hx
Sia il prossimo contatore da visitare.y=((x+1)modc)
Il movimento posiziona il puntatore del nastro su una posizione che è e non a sinistra di .>
×(H+cN+1)≡y(modc)v(y)
Il ciclo interno ora cerca a sinistra nei passi di una cella zero. Se il contatore è zero, allora si fermerà nella cella del valore (zero) ; altrimenti troverà la cella di fallback .[
<
×c c y v ( y ) u ( y )]
cyv(y)u(y)
Qualunque cella venga trovata diventa la nuova cella attiva .
regolazioni
La fase di regolazione regola varie celle sul nastro in base alla loro posizione rispetto alla cella attiva. Questa sezione contiene solo +-><
comandi e quindi queste regolazioni avvengono incondizionatamente. Tuttavia, poiché tutte le celle correlate al contatore sono in un modello di righello Golomb, qualsiasi regolazione non appropriata per la cella attiva corrente mancherà a tutte le celle importanti e regolerà invece alcune celle irrilevanti (mantenendole dispari).
È quindi necessario includere nel programma un codice separato per ogni possibile coppia richiesta di cella attiva e regolata, fatta eccezione per l'autoregolazione di una cella attiva, che, poiché la regolazione si basa esclusivamente sulla posizione relativa, deve essere condivisa tra tutte.
Le regolazioni richieste sono:
- Regola la cella di fallback del contatore precedente di .u(x)−2R
- Regola la cella di fallback del contatore corrente di , tranne se la cella attiva corrente è e quindi dovremmo fermarci.u(y)2Rv(h)
- Regola la cella del valore del contatore successivo di (decrementando il contatore).v((y+1)modc)−2
- Quando la cella attiva è una cella di valore (quindi il contatore ha raggiunto lo zero), regolare tutte le celle di valore di dalla mappa di trigger TWM. stesso viene regolato da .v(y)yv(z)2f(y,z)v(y)2R
Il primo e secondo suddette regolazioni sono rese necessarie dal fatto che tutte le cellule attive devono adeguarsi stessi per lo stesso valore, che è per le cellule valore, e quindi anche per le cellule di ripiego. Ciò richiede la preparazione e la pulizia delle celle di fallback per garantire che tornino a in entrambi i rami valore e fallback.2R0
Fine dell'anello esterno
Il movimento rappresenta che al termine della fase di regolazione, il puntatore del nastro viene spostato in posizioni a sinistra della cella attiva.<
×HH
Per tutte le celle attive diverse dalla cella del valore del contatore di arresto , questa è una cella irrilevante, quindi dispari e diversa da zero, e il ciclo esterno continua per un'altra iterazione.v(h)
Per , il puntatore viene invece posizionato sulla corrispondente cella di fallback , per la quale abbiamo fatto un'eccezione sopra per mantenerlo zero, e quindi il programma esce attraverso il finale e si ferma.v(h)u(h)]