Programmation en deux dimensions temporelles

17

C'est un drôle d'accident que ce monde ne possède qu'une seule dimension temporelle, mais il ne doit pas nécessairement en être ainsi. Il est facile d'imaginer des mondes avec 2 dimensions temporelles ou plus, et dans ces mondes, vous pourriez construire des ordinateurs et exécuter des logiciels dessus, comme dans celui-ci.

Le système

Voici un système pour exécuter les programmes Brainf * ck en deux dimensions temporelles:

Les deux dimensions temporelles sont x et y. Chaque programme Brainf * ck comprend un demi-programme x et un demi-programme ay, par exemple, un programme

x: +>+
y: [-]

Les deux demi-programmes ont chacun leur propre pointeur de programme, mais ils partagent un seul pointeur de bande (c'est-à-dire qu'ils fonctionnent tous les deux sur la même cellule de la bande).

Le temps est bidimensionnel, il est donc constitué d'une grille de moments:

Une grille de temps 3x3, connexion par actions x et y

En se déplaçant le long de la dimension x, le demi-programme x exécute un pas de temps. En se déplaçant le long de la dimension y, le demi-programme y exécute un pas de temps.

Ainsi, par exemple, supposons que la bande commence comme [0] 0 0( []représente le pointeur de bande) et que les programmes x / y sont +et ->-. L'exécution de ce programme ressemblerait à ceci:

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 >

Notez que, lorsque le temps se déplace dans la direction y, le demi-programme x continue de faire la même chose encore et encore, car son temps ne progresse pas.

La bande à chaque instant inclut l'effet cumulatif de toutes les actions qui y alimentent (chaque action compte une fois). Ainsi, par exemple, la bande au moment (2, 1) contient l'effet cumulatif de:

Quelles actions alimentent un instantané de bande, comme indiqué ci-dessous

  • l'action x de (0, 0)
  • l'action x de (1, 0)
  • l'action x de (0, 1)
  • l'action x de (1, 1)
  • l'action y de (0, 0)
  • l'action y de (1, 0)
  • l'action y de (2, 0)

Cumul signifie:

  • Tous les incréments et décréments d'une somme de cellules ensemble.
  • Tous les mouvements vers la gauche (-1) et la droite (+1) vers le pointeur de bande totalisent ensemble.

Les pointeurs d'instructions ne s'accumulent pas. Chaque demi-programme obtient son pointeur d'instruction à partir du moment précédent dans sa dimension. Autrement dit, les pointeurs de programme x progressent uniquement dans la dimension x et les pointeurs de programme y progressent uniquement dans la dimension y. Ainsi, par exemple, dans le programme ( [], +) à partir de [0] 0 0, l'exécution serait

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

Quelques autres moments de la simulation ci-dessus ( +, ->-) sont:

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

Les opérateurs Brainf * ck autorisés sont les suivants (ils ont leur signification standard):

  • +, -: incrémenter, décrémenter;
  • [, ]: boucle jusqu'à zéro (le traitement d'un [ou ]prend un pas de temps, comme dans Brainf * ck standard);
  • <, >: déplacez-vous vers la gauche / droite sur la bande.

Exemple complexe

Pour le programme ( >, +) commençant par [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

Pour ( +, -) commençant par [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

Notez que la bande se termine comme [0] 0 0chacun +et -se produit deux fois, en additionnant à 0.

Pour le programme ( >+, [-]) commençant par [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

Diagramme avec des flèches

Le diagramme ci-dessous montre comment calculer les actions et la bande:

Diagramme avec des flèches montrant comment les parties du programme sont calculées

Le puzzle

Écrivez un programme 2D Brainf * ck (avec un demi-programme x et un demi-programme ay) à exécuter sur une bande à 3 cellules, qui remplit les deux conditions suivantes:

  • Si la bande commence comme [0] 0 0, au moment (5, 5), elle a un 0dans la cellule zéro.
  • Si la bande commence comme [1] 0 0, au moment (5, 5), elle a un 0dans la cellule zéro.

Le programme le plus court répondant aux exigences l'emporte.

Owen
la source
Juste pour vérifier: quel est le résultat de l'exécution de +et >? Si c'est 1 1 [0](assez fou mais c'est ce que la spécification semble suggérer), comment les pointeurs d'instructions se combinent-ils? Si les deux threads sont +et [], alors 1 2la bande de données serait [3], mais le deuxième pointeur d'instruction est-il à l'intérieur de la boucle ( []+chemin), ou à l'extérieur ( [+]chemin) ou même illégal ( +[])?
John Dvorak
@JanDvorak Ah, je pense que je vois ce que vous demandez. J'ai oublié d'ajouter que chaque programme obtient son pointeur d'instruction à partir du moment adjacent dans sa dimension. Je vais modifier cela dans, et essayer d'exécuter ( +, >) pour voir si j'obtiens le même résultat que vous.
Owen
C'est un beau défi mais il a besoin d'un critère de gain objectif pour pouvoir classer les réponses.
Martin Ender
3
Le défi n'est toujours pas vraiment clair pour moi. Comment le temps avance-t-il exactement à travers la grille? D'après votre graphique, il semble que je puisse arriver à (1,1)travers l'un (1,0)ou l' autre (0,1), mais si un programme commence par >et l'autre commence par +, alors leur ordre relatif est-il important?
Martin Ender

Réponses:

8

4 octets au total: ( [-], >)

J'ai écrit un brute-forcer pour trouver le plus petit programme de ce type.

Voici les schémas de ce programme en action. Ces grilles sont disposées de manière similaire à la grille de la spécification, avec (0,0) le coin inférieur gauche, le temps x le long de l'axe x et le temps y le long de l'axe y. Le coin supérieur droit contient le résultat.

Tout d'abord, avec une bande de 0 0 0:

|  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|( 0)  0   0 |( 0)  0   0 |( 0)  0   0 |( 0)  0   0 |( 0)  0   0 |( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|(>)         |(>)         |(>)         |(>)         |(>)         |(>)         
+------------+------------+------------+------------+------------+------------

Maintenant avec une bande de 1 0 0:

|  1 ( 0)  0 |  1   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|  1 ( 0)  0 |  1   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|  1 ( 0)  0 |  1   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|  1 ( 0)  0 |  1   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|  1 ( 0)  0 |  1   0 ( 0)|( 0)  0   0 |  0 ( 0)  0 |  0   0 ( 0)|( 0)  0   0 
|([)-]       |[-]         |[-]         |[-]         |[-]         |[-]         
|>           |>           |>           |>           |>           |>           
+------------+------------+------------+------------+------------+------------
|( 1)  0   0 |( 1)  0   0 |( 0)  0   0 |( 0)  0   0 |( 0)  0   0 |( 0)  0   0 
|([)-]       |[(-)]       |[-(])       |[-]         |[-]         |[-]         
|(>)         |(>)         |(>)         |(>)         |(>)         |(>)         
+------------+------------+------------+------------+------------+------------

Il y avait quelques choses qui n'étaient pas clairement expliquées dans la spécification, comme le fait que la bande à 3 cellules s'enroule.


En bonus, voici la visualisation de l' exemple ( >+, [-]):

|( 0)  0   0 |( 0)  0   0 |( 1)  1   0 
|(>)+        |>(+)        |>+          
|[-]         |[-]         |[-(])       
+------------+------------+------------
|( 0)  0   0 |  0   0 ( 0)|  0   1 ( 1)
|(>)+        |>(+)        |>+          
|[-]         |[-]         |[(-)]       
+------------+------------+------------
|( 0)  0   0 |  0 ( 0)  0 |  0 ( 1)  0 
|(>)+        |>(+)        |>+          
|([)-]       |([)-]       |([)-]       
+------------+------------+------------

Et l'un des exemples ( >+, +>):

|( 1)  0   0 |  1   1 ( 0)|  1   3 ( 1)
|(>)+        |>(+)        |>+          
|+(>)        |+(>)        |+(>)        
+------------+------------+------------
|( 0)  0   0 |  0 ( 0)  0 |  0 ( 1)  0 
|(>)+        |>(+)        |>+          
|(+)>        |(+)>        |(+)>        
+------------+------------+------------

Notez que le coin supérieur droit est différent de ce que vous avez répertorié, je pense que c'est une erreur dans votre exemple car mon code correspond à tous les autres exemples que j'ai essayés.

PhiNotPi
la source
Ceci est incroyable! Vous avez peut-être raison sur l'erreur. Je vais le vérifier à nouveau.
Owen