È un incidente divertente che questo mondo abbia solo una dimensione temporale, ma non deve essere così. È facile immaginare mondi con 2 o più dimensioni temporali e in quei mondi potresti costruire computer ed eseguire software su di essi, proprio come in questo.
Il sistema
Ecco un sistema per eseguire i programmi Brainf * ck in due dimensioni temporali:
Le due dimensioni temporali sono xey. Ogni programma Brainf * ck è costituito da un mezzo programma x e un mezzo programma, ad esempio un programma potrebbe essere
x: +>+
y: [-]
I due semi-programmi hanno ciascuno il proprio puntatore al programma, ma condividono un singolo puntatore a nastro (ovvero, entrambi operano sulla stessa cella del nastro).
Il tempo è bidimensionale, quindi è costituito da una griglia di momenti:
Spostandosi lungo la dimensione x, il mezzo programma x esegue un passaggio temporale. Muovendosi lungo la dimensione y, il mezzo programma y esegue un passo temporale.
Ad esempio, supponiamo che il nastro inizi come [0] 0 0
( []
rappresenta il puntatore del nastro) e che i programmi x / y siano +
e ->-
. L'esecuzione di questo programma sarebbe simile a questa:
x y tape x-action y-action
0 0 [ 0] 0 0 + at 0 - at 0
1 0 [ 1] 0 0 (done) - at 0
0 1 [-1] 0 0 + at 0 move >
1 1 [ 0] 0 0 (done) move >
Si noti che, man mano che il tempo si sposta nella direzione y, il mezzo programma x continua a fare la stessa cosa più e più volte, perché il suo tempo non progredisce.
Il nastro in ogni momento include l'effetto cumulativo di tutte le azioni che lo alimentano (ogni azione conta una volta). Quindi, ad esempio, il nastro at time (2, 1) contiene l'effetto cumulativo di:
- l'azione x da (0, 0)
- l'azione x di (1, 0)
- l'azione x di (0, 1)
- l'azione x di (1, 1)
- l'azione y di (0, 0)
- l'azione y di (1, 0)
- l'azione y di (2, 0)
Cumulativo significa:
- Tutti gli incrementi e i decrementi in una cella vengono sommati insieme.
- Tutti i movimenti sinistro (-1) e destro (+1) verso il puntatore del nastro vengono sommati.
I puntatori alle istruzioni non si accumulano. Ogni mezzo programma ottiene il puntatore di istruzione dal momento precedente nella sua dimensione. Ossia, i puntatori del programma x avanzano solo nella dimensione x e i puntatori del programma y avanzano solo nella dimensione y. Quindi, ad esempio, nel programma ( []
, +
) a partire da [0] 0 0
, l'esecuzione sarebbe
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 0 0 0 + at 0 0 0
1 0 0 0 0 + at 0 2 (from jump) 0
0 1 1 0 0 0 1
1 1 2 0 0 1 (from NO jump) 1
Alcuni altri momenti della simulazione ( +
, ->-
) sopra sono:
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 [ 0] 0 0 + at 0 - at 0 0 0
1 0 [ 1] 0 0 - at 0 1 0
2 0 [ 1] 0 0 - at 0 1 0
0 1 [-1] 0 0 + at 0 > 0 1
1 1 [ 0] 0 0 > 1 1
2 1 [-1] 0 0 > 1 1
0 2 -1 [ 0] 0 + at 1 - at 1 0 2
1 2 0 1 [ 0] - at 2 1 2
2 2 [-1] 1 0 - at 0 1 2
Gli operatori Brainf * ck consentiti sono i seguenti (hanno il loro significato standard):
+
,-
: incremento, decremento;[
,]
: loop fino a zero (elaborazione di a[
o]
richiede una fase temporale, come nello standard Brainf * ck);<
,>
: sposta a sinistra / a destra sul nastro.
Esempio complesso
Per il programma ( >
, +
) che inizia con [0] 0 0
:
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 [ 0] 0 0 > + at 0 0 0
1 0 0 [ 0] 0 + at 1 1 0
0 1 [ 1] 0 0 > 0 1
1 1 1 1 [ 0] 1 1
Per ( +
, -
) che inizia con [0] 0 0
:
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 [ 0] 0 0 + at 0 - at 0 0 0
1 0 [ 1] 0 0 - at 0 1 0
0 1 [-1] 0 0 + at 0 0 1
1 1 [ 0] 0 0 1 1
Si noti che il nastro termina come [0] 0 0
perché ciascuno +
e si -
verifica due volte, sommando a 0.
Per il programma ( >+
, [-]
) che inizia con [0] 0 0
:
x y tape x-action y-action x-prog-ptr y-prog-ptr
0 0 [ 0] 0 0 > 0 0
1 0 0 [ 0] 0 + at 1 1 0
2 0 0 [ 1] 0 2 0
0 1 [ 0] 0 0 > 0 3
1 1 0 0 [ 0] + at 2 1 3
2 1 0 1 [ 1] - at 2 2 1
0 2 [ 0] 0 0 > 0 3
1 2 [ 0] 0 0 + at 0 1 3
2 2 [ 1] 1 0 2 2
Schema con le frecce
Il diagramma seguente mostra come calcolare le azioni e il nastro:
Il puzzle
Scrivi un programma Brainf * ck 2D (con un mezzo programma x e un mezzo programma x) da eseguire su un nastro a 3 celle, che soddisfi entrambe le seguenti condizioni:
- Se il nastro inizia come
[0] 0 0
, al momento (5, 5) ha un0
nella cella zeroth. - Se il nastro inizia come
[1] 0 0
, al momento (5, 5) ha un0
nella cella zeroth.
Vince il programma più breve che soddisfa i requisiti.
+
, >
) per vedere se ottengo lo stesso risultato.
(1,1)
attraverso uno (1,0)
o (0,1)
, ma un programma inizia con >
uno e inizia con uno +
, quindi sicuramente il loro ordine relativo è importante?
+
e>
? Se è1 1 [0]
(piuttosto pazzo ma è ciò che le specifiche sembrano suggerire), come si combinano i puntatori alle istruzioni? Se i due thread sono+
e[]
, quindi sul1 2
nastro dati lo sarebbe[3]
, ma il secondo puntatore all'istruzione è all'interno del ciclo ([]+
percorso), o all'esterno ([+]
percorso) o addirittura illegale (+[]
)?