Dans ce défi, vous écrirez un interprète pour 2 Ω (transcrit en TwoMega ), un langage basé vaguement sur le brainfuck avec un espace de stockage de dimension infinie.
La langue
2 Ω contient trois éléments d'état:
La bande , qui est une liste infinie de bits, tous initialisés à 0. Elle a un élément le plus à gauche, mais pas d'élément le plus à droite.
Le pointeur de mémoire , qui est un entier non négatif qui est un index d'un élément de la bande. Un pointeur de mémoire supérieur fait référence à une cellule de bande plus à droite; un pointeur de mémoire de 0 fait référence à l'élément le plus à gauche. Le pointeur de mémoire est initialisé à 0.
L' Hypercube , qui est une "boîte" de cellules conceptuellement ∞- dimensionnelle, dont chacune contient un bit initialisé à 0. La largeur de l'Hypercube est liée dans chaque dimension à seulement 2 cellules, mais l'infinité des dimensions signifie le nombre de les cellules sont innombrables .
Un index dans l'hypercube est une liste infinie de bits qui fait référence à une cellule de l'hypercube (de la même manière qu'une liste finie de bits pourrait être utilisée pour faire référence à un hypercube de dimension finie). Parce que la bande est une liste infinie de bits, la bande entière se réfère toujours à un élément de l'hypercube; cet élément est appelé référent .
2 Ω donne un sens à 7 caractères différents:
<
décrémente le pointeur de mémoire de 1. Le décrémenter en dessous de 0 est un comportement indéfini, vous n'avez donc pas besoin de le gérer.>
incrémente le pointeur mémoire de 1.!
retourne le bit au référent..
sort le bit au référent.^
remplace le bit de la cellule pointée par le pointeur de mémoire sur la bande par l' inverse du bit du référent.[x]
exécute le codex
tant que le bit au référent est 1.
Le défi
Votre tâche consiste à écrire un programme qui prend une chaîne en entrée et exécute cette entrée en tant que programme 2 Ω .
Il s'agit de code-golf , donc la réponse valide la plus courte (mesurée en octets) l'emporte.
Remarques
- Vous pouvez supposer que le programme se composera uniquement des caractères
<>!.^[]
et qu'il[]
sera correctement imbriqué. - Votre interprète ne doit être limité que par la mémoire disponible sur le système. Il doit pouvoir exécuter les exemples de programmes dans un délai raisonnable.
Exemples de programmes
Imprimer 1:
!.
Imprimer 010:
.!.!.
Imprimer 0 pour toujours:
![!.!]
Imprimez 0 pour toujours ou 1 pour toujours si !
est ajouté:
[.]![!.!]
la source
1
s sur la bande est toujours fini. En fait, il existe une bijection assez simple entre les nombres naturels et les états de bande (interpréter le contenu de la bande comme un nombre binaire en arrière), ce qui montre que le Hypercube est fondamentalement un tableau 1D infini, accessible en retournant les bits dans une valeur de pointeur entier , au lieu d'in / décrémenter comme dans brainfuck.cat
programme: il ne semble pas y avoir d'instructions pour la saisie..
- imprime un seul zéro puis existe;!^!.
- imprime un seul puis quitte. Plus serait bien cependant. Pour le moment, il faut comprendre les soumissions afin de les vérifier (et donc de les voter!)[0,0,0,0,0,0,0...]
(c'est-à-dire la présence d'un!
au début du programme).[.]![!.!]
pour imprimer la valeur de cette cellule pour toujoursRéponses:
Python 2 , 167 octets
Essayez-le en ligne!
t est la bande. t = 6 signifie que la bande est [0 1 1 0 0 0…]
m est 2 à la puissance du pointeur mémoire. Donc m = 8 signifie que nous pointons sur le bit de bande 3.
h est l'hypercube. h = 80 (bits 4 et 6 définis) signifie que les bits à [0 0 1 0…] et [0 1 1 0…] sont définis.
Pour lire le bit chez le référent, on vérifie 2 t & h . Pour le retourner, nous effectuons h ^ = 2 t .
Nous traduisons les instructions en code Python et exécutons le résultat. Je stocke le niveau d'indentation des boucles while.
la source
2**t
(-6 octets).JavaScript (Node.js) , 148 octets
Essayez-le en ligne!
C'est complet
Besoin d'init comme se déplaçant vers la droite à quelques endroits et initialiser le bit actuel et à droite de l'adresse comme 1 (
>>>>>>>>^>^<
)Essayez-le en ligne!
La place
n
dans BoolFuck s'écrit(0, 0, ..., 0(n*0), [1], 1, 0, 0, ...)
.Car
>
, c'est le casn
=>n+1
Comme pour le
<
travailla source
!>.
imprime1
dans boolfuck mais se traduit par!>^.
lequel imprime 1 dans TwoMega (>
n'affecte pas la bande;^
n'affecte pas la bande puisque le référent est 1)+>;
do[1]00...
1[0]0...
(sortie 0),!>^.
do(0,0,...)=1, ptr=([0],0,...)
(0,0,...)=1, ptr=(0,[0],...)
(0,0,...)=1, ptr=(0,[1],...)
(sortie 0), qu'est-ce qui ne va pas?!>.
, seule>
est une commande valide dans boolfuck ...!
inverse le référent, pas la cellule de bande.Brain-Flak Classic , 816 octets
Essayez-le en ligne!
Ce code a été écrit juste pour que j'aie un endroit pour écrire une preuve d'exhaustivité de Turing.
Preuve de complétude de Turing
Nous montrons une réduction de Boolfuck à TwoMega:
Cette traduction stocke l'état Boolfuck dans les cellules de bande paires dans TwoMega. Toutes les commandes traduites conserveront les invariants suivants:
L'extrait
!^!
restera[0]0
constant et échangera entre0[0]
et[1]1
(où l'attention est limitée à la ligne sur l'hypercube accessible sans déplacer le pointeur de mémoire). En tant que tel, il est utilisé pour placer temporairement la valeur de bande actuelle dans le référent pour les commandes Boolfuck qui s'en soucient.Si TwoMega recevait une commande d'entrée
,
avec la sémantique attendue, la commande Boolfuck,
se traduirait par>^<,!^>[!]!^<
. Puisqu'il,
n'est pas nécessaire de prouver que Boolfuck est Turing-complete, l'absence d'une commande d'entrée n'affecte pas cette preuve.la source
Python 3 ,
297284274 octets-10 octets grâce aux ovs et Jonathan Allan
Essayez-le en ligne!
la source
t.discard(p)
->t-={p}
t
c'est le casglobal
.f
commef(C,p,t=set())
Pip ,
7571 octetsEssayez-le en ligne!
Traduit le code 2 Ω en code Pip équivalent et l'évalue.
Nous utilisons
i
pour représenter la bande,v
pour le pointeur de bande * etl
pour l'hypercube. Les deux premiers sont pré-initialisés à des valeurs utiles;l
commence par[]
, auquel nous poussons un0
(lPU0
) pour éviter les problèmes d'indexation-liste vide.* En fait, c'est la négation au niveau du bit du pointeur de bande, car nous stockons la bande en arrière pour une conversion plus facile en décimal.
Le reste du code est:
La table de traduction:
l@FBi
est l'élément référent: de l'hypercubel
à l'index (convertiri
du binaire). Il apparaît souvent, nous l'appelons donc_
et le remplaçons_
par le vrai code à la fin.!:_
nie logiquement le référent en place.--viPU0
décrémentationsv
(déplacement du pointeur de bande vers la droite); il en pousse ensuite un autre0
vers la gauchei
pour s'assurer que le pointeur de bande reste dans les limites.++v
incrémentsv
(pas besoin de vérification des limites, par OP).W_{
exécute une boucle pendant que le référent est véridique (ie non nul, ie1
).}
ferme la boucle.O_
affiche le référent sans nouvelle ligne.Enfin, pour
^
:la source