Interprète de langue Turing-Complete


42

Un défi qui, selon moi, serait très intéressant est de faire appel à un interprète pour une langue complète de Turing de votre choix.

Les règles sont simples:

  1. Vous pouvez utiliser n’importe quel langage pour créer cet interprète, même s’il est plus récent que ce défi.
  2. Vous pouvez utiliser n'importe quel langage complet de Turing tant qu'il n'est pas identique à celui avec lequel vous l'écrivez.
  3. Vous ne pouvez pas simplement évaluer du code, par exemple, utiliser des fonctions eval.
  4. Une explication de la façon dont vous avez abordé cette question sera utile mais pas obligatoire.
  5. Cela sera noté en octets.
  6. Chaque soumission doit fonctionner pleinement, ce qui signifie que chaque caractéristique de la langue choisie doit être présente.

Pour être dit simplement:

Votre tâche consiste à créer un interprète de travail pour n’importe quelle langue complète de Turing avec la langue de votre choix.

Bonne chance!


3
Je recommanderais également une règle selon laquelle le langage implémenté doit être différent du langage que vous utilisez pour l'implémenter, afin d'éviter les evalsolutions triviales .
ETHproductions

1
En fait, vous voudrez peut-être simplement interdire les evalcommandes / fonctions, car certaines langues ont des fonctions intégrées pour évaluer le code dans une autre langue.
ETHproductions 25/02/2017

2
@arodebaugh Pour les défis à venir, vous pouvez publier votre idée dans le bac à sable où vous pouvez obtenir des commentaires et résoudre les détails de ce type avant que les défis ne deviennent réalité et que des réponses ne soient données.
Martin Ender

1
OK, vous devriez probablement être un peu plus spécifique et dire quelque chose comme: "Vous ne pouvez pas simplement exécuter du code, par n'importe quelle méthode" pour éviter d'autres réponses triviales comme celle de Bash + perl.
ETHproductions

Réponses:


16

Brachylog (2) → Problème de correspondance , 9 octets

~h=∋ᵐ\cᵐ=

Essayez-le en ligne!

L'entrée est une liste de listes de chaînes. (Dans le problème de correspondance Post tel que défini sur Wikipedia, les listes internes ont deux éléments chacun, bien que ce programme puisse en réalité gérer une généralisation à un nombre quelconque d'éléments.) une solution est trouvée. On sait que le problème de correspondance avec la poste est capable de simuler une machine de Turing, et que les solutions qui en découlent sont donc complètes. Si elle est exécutée comme une fonction plutôt que comme un programme, elle produit également un résultat significatif.

Le programme dans le lien TIO ci-dessus est [["a","baa"],["ab","aa"],["bba","bb"]], que j'ai copié de Wikipedia. La solution (que le programme trouve assez rapidement) est ["bbaabbbaa","bbaabbbaa"].

Explication

C’est quasiment une traduction directe du problème de correspondance de Post avec Brachylog.

~h=∋ᵐ\cᵐ=
~h         Find {the shortest possible} list which starts with {the input}
  =        and for which all elements are equal
   ∋ᵐ      such that taking an element of each element,
     \cᵐ   and concatenating elements in corresponding positions,
        =  produces a list all of whose elements are equal.

Fondamentalement, nous créons une liste composée de copies répétées de l'entrée (aussi peu que possible, ce qui signifie que nous ne manquons aucune possibilité lorsque nous le forçons), prenons un élément de chaque copie, puis concaténons les éléments correspondants (comme dans la correspondance Post problème).


1
Et l’habituel "récapitulatif des choses significatives qui économiseraient des octets, mais que l’interprète de Brachylog ne pourrait pas gérer": les cinq premiers octets pourraient être exprimés sous la forme ~dp(ce qui ne signifie pas tout à fait la même chose mais est assez proche pour être encore Turing-complete), sauf que l'interprète Brachylog ne sait pas encore comment inverser d.

12

Jelly → "Ajouter minimum à transposer", 5 à 4 octets

+"Ṃẞ

Essayez-le en ligne! (exécute une seule itération, pour éviter les délais d'attente)

Une construction très simple de Turing-complete: nous prenons une matrice carrée comme programme et bouclons pour toujours, en identifiant la rangée lexicographiquement la plus petite, puis en augmentant chaque élément de la première ligne par le premier élément du lexicographiquement le plus petit, chaque élément de la deuxième ligne par le deuxième élément du plus petit lexicographe, et ainsi de suite. (Le programme Jelly est " +"ajoute les éléments correspondants {de l'entrée et} le minimum {de l'original}, boucle"; il s'agit d'un octet plus court que mon programme précédent Z+ṂZß, qui faisait exactement la même chose. J'aurais clairement dû me concentrer sur le golf La gelée, pas seulement le golf dans la langue implémentée.)

La langue résultante est Turing-complete pour la même raison que Kangaroo.. Le premier élément de chaque ligne agit comme un nombre de sauts (bien que, au lieu du nombre de sauts de chaque commande, il augmente le nombre de sauts de chaque commande lorsqu'il est exécuté et recherche la commande avec le plus petit nombre de sauts. que les commandes avec zéro sauts compte, cela revient à la même chose). Nous nous assurons que ce premier élément est supérieur aux autres éléments (qui représentent le nombre de fois que chaque commande apparaît dans le multiset de chaque commande), en nous assurant ainsi que la première ligne n'est jamais le minimum; le reste de la première ligne peut être un déchet. Le seul problème qui reste est de modéliser la façon dont les commandes avec un nombre de sauts égal s'exécutent de manière cyclique, mais nous pouvons le faire en multipliant tous les comptes de saut par une grande constante, puis en ajoutant un petit "initial". sauter compte jusqu'à la première colonne pour servir d'égalité. Cela nous donne un tie-break de "première commande non compressée exécutée", et non pas "des commandes non programmées exécutées cycliquement en séquence", mais la construction de complétude de Turing pour Kangourou ne se soucie pas de cette différence.


10

Mathematica interprétant le jeu de la vie de Conway, 64 octets

CellularAutomaton@{224,{2,{t={2,2,2},{2,1,2},t}},{1,1}}~Nest~##&

Le jeu de la vie de Conway est connu pour être complet de Turing; et les automates cellulaires sont la véritable obsession de Stephen Wolfram. CellularAutomaton@{224,{2,{t={2,2,2},{2,1,2},t}},{1,1}}est une règle qui transforme un tableau bidimensionnel de 0 et de 1 en une étape du jeu de la vie de Conway. (Je pense que le comportement par défaut est enveloppé par cette matrice autour de ses bords, donc est vraiment un tore discret.) ~Nest~##&Transforme cette règle dans une fonction qui, lorsqu'elle est administrée un état de bord initial (de dimensions quelconques) et un nombre entier nd'arguments, délivre en sortie le résultat des nitérations de la règle du jeu de la vie.

Pour votre propre plaisir, vous pouvez utiliser la version enveloppée

b = RandomInteger[1,{50,50}];
Manipulate[ArrayPlot[
  CellularAutomaton@{224,{2,{t={2,2,2},{2,1,2},t}},{1,1}}~Nest~##&
    [b, n] ]
, {{n,0}, 0, 100, 1}]

et faites défiler votre chemin à travers 100 générations sur un tableau 50x50.


Si je comprends bien, la taille du tableau est-elle fixe? Dans ce cas, je pense que ça ne peut pas être Turing-complete, n'est-ce pas?
DLosc

Tout appel particulier à la fonction a une taille de carte fixe, mais cette taille de carte peut être arbitrairement grande. (Notez que la seconde partie de l'article décrit un exemple d'observation du code en action, pas le code lui-même.)
Greg Martin

Ce que je dis, c'est que pour que GoL soit Turing-Complete, il doit être capable d'un motif qui se développe à l'infini. (Par exemple, un canon de planeur.) Si cette implémentation ne peut pas agrandir le tableau d'une étape à une autre, mais l'enveloppe de manière toroïdale à la place, le test de la croissance infinie échoue.
DLosc

C'est une perspective raisonnable, pour être sûr. Mais les implémentations de langages de programmation sur des ordinateurs physiques ne répondent même pas à ce test! On pourrait se contenter d'une séquence (hypothétique) d'ordinateurs physiques avec de plus en plus de mémoire, chacun capable de calculer une valeur de plus de cette fonction calculable; à ce stade, cependant, il convient également de se contenter d'une séquence (hypothétique) d'entrées pour un tel programme GoL.
Greg Martin

9

Tortue interprétant CT , 49 octets

Je pourrais peut-être jouer au golf cette

En outre, cela ne produit rien d’utile. il ne fait que s'arrêter si et seulement si le programme CT donné est arrêté.

c’est celui que j’ai fait il ya quelque temps en fait (puis en golfant maintenant)

!-l[*+.r_]' !l[ l]r[ u.(;d' u)d(1[ r].[ l])( r)+]

Comment ça marche:

Turtlèd utilise des cellules de grille. Quand je dis "écris quelque chose sur la grille", je veux dire qu'un groupe de caractères contigu est placé sur la grille. Exemple

[ ][ ][ ][ ][ ][ ][ ]
[ ][H][E][L][L][O][ ]
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ]

sur le programme

les données sont entrées en premier:

!-l[*+.r_]' 

c'est essentiellement un programme pour chats. il écrit l'entrée sur la grille.

alors les commandes sont entrées:

!

ce qu'il fait avec ces commandes:

ces commandes sont des "productions". si le bit de données le plus à gauche est 1, la production est copiée à la fin de la chaîne de données. sinon rien ne se passe. ensuite, le bit de données le plus à gauche est supprimé et il utilise la production suivante avec le prochain bit de données le plus à gauche. le programme s'arrête lorsqu'il n'y a pas de bits dans la chaîne de données. Une façon de faire ces productions est de traiter les bits et la fin des productions séparément. C'est ce que fait notre programme. il copie séparément les bits de la chaîne de commande jusqu'à la fin de la chaîne de données et supprime séparément les bits de la datastring

sur comment ce programme le fait. après avoir entré les commandes, le pointeur tortue / grille revient au bit le plus à gauche du datastring. il passe ensuite dans une boucle

[ u.(;d' u)d(1[ r].[ l])( r)+]

ce qu’il fait dans cette boucle, c’est qu’il monte du datastring le plus à gauche et écrit le caractère de commande en cours (u.). si c'est le cas, la fin d'une production, il descend et supprime le bit de données le plus à gauche situé en dessous et remonte ( (;d' u)). alors, dans tous les cas, il descend d'un ( d). si le bit n’a pas été supprimé, cela signifie qu’il doit vérifier s’il convient de copier un bit à partir des commandes à la fin. ainsi, si ce caractère qui est ou était le bit de donnée le plus à gauche est un 1, il se déplacera à la fin de l'extrémité droite de la chaîne de données, copiera le bit de la chaîne de commande et reviendra dans l'espace à gauche des données les plus à gauche. bit ( (1[ r].[ l])). maintenant, c'est soit sur le bit de donnée le plus à gauche, qui était un zéro, soit à gauche du bit de donnée le plus à gauche. alors, on bouge bien si sur un espace (( r)). ensuite, le pointeur de commande est incrémenté, nous allons donc écrire la prochaine commande lors de la prochaine itération de la boucle. S'il n'y a plus de datastring, cela signifie que nous serons sur un espace et la boucle se terminera. sinon, nous réexécutons la boucle.


Essayez de jouer au golf plus!
arodebaugh

9

Perl → Variante Trois étoiles , 26 + 1 = 27 octets

++$a[$a[$a[$_]]]for@F;redo

Essayez-le en ligne! (Ce lien contient un en-tête qui quitte le programme après un nombre défini d'itérations (pour que TIO ne s'éteigne pas) et pour afficher l'état interne à chaque itération (afin qu'il fasse une chose observable).)

Courez avec -a(pénalité de 1 octet, comme vous pouvez l’intégrer avant -M5.010de produire -aM5.010).

Plus précisément, cela implémente Three Star Programmer dans lequel les commandes sont séparées par des espaces et aucun commentaire n'est autorisé dans le fichier, sans extensions d'E / S. (Ces modifications ne font évidemment aucune différence pour la complétude en langue de Turing, bien sûr.) Il n’ya pas de preuve de complétude en ligne pour Three Star Programmer en ligne, mais elle est complète (j'ai partagé un croquis de preuve de Turing). avec les autres esoprogrammeurs, mais a arrêté de travailler sur la langue lorsque j’ai découvert qu’il était en fait assez facile de programmer une fois que l’on avait surmonté le choc initial).

Le programme n'a pas vraiment besoin de beaucoup d'explications; Three Star Programmer a une spécification très simple, qui en est une traduction directe. Les seuls points subtils: @Fest l’entrée du programme sous forme de tableau (c’est une conséquence de -a); et redorépétera le programme dans son intégralité, comme dans une boucle implicite (également une conséquence de -a).


1
Je pense qu'il est plus logique que la flèche signifie "est réduit à" que "interprète".
Quintopia

9

Assemblage x86 (syntaxe Intel / MASM) - Brainfuck 2127 octets.

Golf encore capable

.386
.model flat,stdcall
.stack 4096
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
ExitProcess proto,dwExitCode:dword
.data
bfsrc BYTE 200 dup(0) 
bfcells BYTE 100 dup(0) 
loopStack DD 5 dup(0) 
charBuf BYTE 5 dup(0) 
newline BYTE 10,0 
prompt BYTE "$",0 
hr BYTE 50 dup('-'),0 
space BYTE ' ',0
.code
EvalBf proc
    start:
    invoke StdOut, addr prompt
    invoke StdIn, addr bfsrc,200
    cmp bfsrc,0
    je exit
    mov eax,0 
    mov ebx,0 
    mov ecx,0 
    processInstruction:
    cmp BYTE PTR bfsrc[ebx], '+'
    je plus
    cmp BYTE PTR bfsrc[ebx], '-'
    je minus
    cmp BYTE PTR bfsrc[ebx], '>'
    je fwd
    cmp BYTE PTR bfsrc[ebx], '<'
    je back
    cmp BYTE PTR bfsrc[ebx], '['
    je open
    cmp BYTE PTR bfsrc[ebx], ']'
    je close
    cmp BYTE PTR bfsrc[ebx], '.'
    je dot
    jmp processNextInstruction
    plus:
    inc BYTE PTR bfcells[eax]
    jmp processNextInstruction
    minus:
    dec BYTE PTR bfcells[eax]
    jmp processNextInstruction
    fwd:
    inc eax
    jmp processNextInstruction
    back:
    dec eax
    jmp processNextInstruction
    open:
    mov loopStack[ecx*4],ebx
    inc ecx
    jmp processNextInstruction
    close:
    dec ecx
    cmp BYTE PTR bfcells[eax], 0
    je processNextInstruction
    mov ebx,loopStack[ecx*4]
    inc ecx
    jmp processNextInstruction
    dot:
    mov dl, BYTE PTR bfcells[eax]
    mov BYTE PTR charBuf[0], dl
    mov BYTE PTR charBuf[1],0anything
    push eax
    push ecx
    invoke StdOut, addr charBuf
    pop ecx
    pop eax
    jmp processNextInstruction
    processNextInstruction:
    inc ebx
    cmp BYTE PTR bfsrc[ebx], 0
    je done
    jmp processInstruction
    done:
    invoke StdOut, addr newline
    mov eax, 0
    printNext:
    cmp eax, 100
    jge reset
    push eax
    invoke dwtoa, BYTE PTR bfcells[eax], addr charBuf
    invoke StdOut, addr charBuf
    invoke StdOut, addr space
    pop eax
    inc eax
    jmp printNext
    reset:
    invoke StdOut, addr newline
    invoke StdOut, addr hr
    invoke StdOut, addr newline
    jmp start

    exit:
    invoke ExitProcess,0
EvalBf endp
end EvalBf

3
Habituellement, les réponses d'assemblage sont comptées dans la taille du code machine obtenu. Vous n'avez donc pas besoin de jouer l'assemblage du tout, mais minimisez le nombre / la taille des instructions.
Robert Fraser

@RobertFraser euh je ne sais pas comment compter ça: P
Christopher

3
En fait, au début, je lisais le titre comme "x86 asm implémenté dans Brainfuck" et
j'étais

@Quetzalcoatl Ce serait impressionnant
Christopher

1
Nom des variables / libellés de golf ty
ASCII uniquement

8

Pip interprétant les systèmes de balises cycliques , 16 octets

YqWyyPBg@++vXPOy

Prend les productions du système de balises en tant qu'arguments de ligne de commande et la chaîne de données initiale de stdin.

Le code ci-dessus est un peu difficile à vérifier car il ne produit aucune sortie (le seul comportement observable est donc "se termine" ou "ne se termine pas"). Par conséquent, voici une version non golfée qui sort la chaîne de données après chaque étape et se termine après 20 étapes pour que TIO n'ait pas à traiter des tonnes de sorties de boucles infinies: essayez-le en ligne!

Systèmes de balises cycliques

Les systèmes de balises cycliques constituent un modèle informatique extrêmement simple mais complet de Turing . Ils consistent en une liste de productions qui définissent des opérations sur une chaîne de données . Les productions et la chaîne de données sont composées de 1 et de 0.

A chaque étape, le caractère le plus à gauche de la chaîne de données est supprimé.

  • Si le caractère est 1, la production en cours est ajoutée à droite de la chaîne de données.
  • Si le caractère est 0, rien n'est ajouté.

Dans les deux cas, la production actuelle passe à la production suivante de la liste, de manière cyclique: si nous en étions à la dernière production, nous passons à la première. L'exécution continue jusqu'à ce que la chaîne de données soit vide.

Explication

                  g is list of cmdline args; v is -1 (implicit)
 q                Read a line of stdin for the data string
Y                 and yank it into the y variable
  Wy              While data string is nonempty:
       g@++v       Retrieve the next production from g (using cyclic indexing)
             POy   Pop the first character of y
            X      String-multiply: result is the production if the first character of y
                   was 1, or empty string if it was 0
    yPB            Push that string to the back end of y

hé, je viens de me rappeler que vous n’avez pas besoin de saisir la chaîne de données; il peut simplement s'agir d'une 1source: esolangs liens vers cette arxiv.org/abs/1312.6700 . Je vais bientôt modifier ma réponse, et si cela aide votre réponse, vous devriez (votre contribution semble assez amusante en fait)
Citron destructible

8

Fonctions de Collatz généralisées itérées -> Python 2, 46 octets

a,b,x,m=input()
while-~x%m:x=x/m*a[x%m]+b[x%m]

Appelez cette fonction avec une liste de m-1 a et b, la valeur de départ x et le diviseur m, qui constituent collectivement un "programme" pour l'IGCF. Plutôt que de prendre un troisième tableau pour indiquer sur quels modules s'arrêter, ceci s'arrête simplement chaque fois que le module est m-1. Cette simplification signifie que la conversion d’un programme Fractran donné en cette variante peut demander un effort supplémentaire, mais elle enregistre quelques octets dans l’interpréteur.

Essayez-le en ligne! Ce TIO montre comment ajouter 5 + 5 à cette langue. Le programme a = [3], b = [0], m = 2 est additionné et, à partir de 7776 = 2 ^ 5 * 3 ^ 5, donne finalement 59049 = 3 ^ 10.


Bon boulot. J'espérais gagner la prime mais bon travail
Christopher

7

Variante ResPlicate -> Python 2, 47 octets

l=input()
while l:l=l[2+l[0]:]+l[2:2+l[0]]*l[1]

Cette fonction interprète une variante de ResPlicate

  • pour lequel un programme est une liste python de longueur paire, avec des éléments pairs et même des index.
  • sans I / O.
  • pour lequel essayer de copier plus de valeurs qu'il n'en existe dans le reste de la file d'attente copie simplement le reste de la file d'attente (c'est-à-dire que le bit copié n'est pas complété avec des zéros à la longueur requise).

La dernière modification signifie que certains programmes ResPlicate (qui remplissent la première condition) ne se comporteront pas de la même manière dans cette variante, mais heureusement, les interpréteurs BCT n’ont pas besoin de la fonctionnalité supprimée et la langue reste donc TC.

Essayez-le en ligne! Ce TIO contient une impression pour montrer que cela fonctionne, un en-tête qui tue le programme au bout d’une seconde et un exemple qui parvient à générer plus de sorties que ce que TIO peut gérer en une seconde.


2
Pourquoi ne pas l=input()? Serait un octet plus court.
Feersum

7

Perl -amachine I / D , 24 octets

$p=$a[$p]+=$_ for@F;redo

Essayez-le en ligne! (contient un en-tête qui imprime l'état interne et s'arrête après 10 itérations, afin que le comportement soit observable)

À propos de la langue

Ces derniers jours, j'ai travaillé sur la machine I / D , une de mes dernières idées pour des langages de programmation très simples. Cela fonctionne comme suit: le stockage de données consiste en une RAM non limitée, initialement tous des zéros. Chaque élément peut stocker un entier non lié (bien qu'en pratique, la plupart des programmes d'ordinateur I / D ne stockent que de petits entiers dans la plupart d'entre eux, et utilisent les entiers non bornés uniquement comme moyen d'adresser des cellules avec de grandes adresses). Il y a aussi un pointeur de données, qui pointe vers une cellule (c'est-à-dire que l'adresse est stockée sous forme de cellule); c'est initialement aussi zéro.

Il n'y a que deux commandes:

  • I: Incrémente la cellule sur laquelle pointe le pointeur de données. (Le pointeur de données lui-même reste inchangé.)
  • D: Déréférencer le pointeur de données, c'est-à-dire lire la valeur de la cellule vers laquelle pointe le pointeur de données. Puis stockez la valeur résultante que vous avez lue dans le pointeur de données.

L'exécution exécute simplement le programme dans une boucle à plusieurs reprises, pour toujours.

Il est assez surprenant qu'un langage aussi simple soit Turing-complete. Je m'efforce donc de le prouver. Voici la preuve . C'est assez similaire à (mais plus simple que) la preuve de Three Star Programmer, un langage très similaire (et en fait, cette soumission utilise le même "shell" OISC de base autour du programme, ne différant que par les instructions réellement mises en œuvre).

A propos du programme

Usage

L'entrée doit être donnée sur l'entrée standard. Il s'agit d'un programme d'ordinateur I / D sans commentaires, utilisant la syntaxe RLE / OISC. (La machine I / D a deux syntaxes équivalentes différentes, mais pour golfiness ce programme ne prend en charge que l'une d'entre elles.) Dans cette syntaxe, un programme est une séquence de nombres en décimal, représentant la longueur des exécutions de Icommandes entre Dcommandes. (Vous pouvez spécifier deux Dcommandes consécutives ou plus en plaçant une "série de Icommandes 0 " entre elles, la syntaxe est donc très générale.)

Explication

Comme on peut le voir dans le programme, cela n’implémente pas les commandes Iet Dindividuellement. En fait, il s’agit d’un interprète (très légèrement) optimisant (uniquement parce que c’est plus court pour écrire de cette façon). La clé est de voir qu'une série de n commandes d'incrémentation incrémente la cible du pointeur de données n fois, c'est-à-dire lui ajoute n ; et une série de 0 commandes d’incrémentation peuvent également être implémentées de cette façon, car l’ajout de 0 à la mémoire n’a aucun effet. Ainsi , l'opération que nous mettons en œuvre est en fait d'alterner entre la mise en œuvre d' une exécution Of- Is et un D. Ou en d'autres termes, "add nà la valeur indiquée par le pointeur de données (en la mémorisant dans la valeur indiquée par le pointeur de données), puis lisez la valeur indiquée par le pointeur de données et stockez-la dans le pointeur de données ". C'est clairement plus détaillé que nécessaire. pour être, et nous pouvons simplifier davantage ceci en "ajoutant n à la valeur pointée par le pointeur de données, puis stockons cette valeur à la fois dans la cible du pointeur de données et dans le pointeur de données lui-même".

Cela constitue donc le cœur de notre programme. Nous utilisons un tableau $apour stocker la RAM, et en $ptant que pointeur de données (indexation dans le tableau):

$p=$a[$p]+=$_
         + $_  add {the run length}
   $a[$p]      to the element of $a pointed to by $p
   $a[$p] =    storing the result back into that element
$p=            and also in the pointer itself

Perl interprète commodément les éléments non-initialisés du tableau comme étant 0 quand ils sont traités comme des nombres, de sorte que le tableau sera initialisé par zéro à zéro pour nous sans qu'aucun code explicite ne soit nécessaire à cet effet. (Un problème potentiel est l'exactitude numérique lorsque les nombres deviennent grands. Cependant, cela ne se produira que si la quantité de la matrice utilisée dépasse l'espace d'adressage de la machine (les entiers Perl sont suffisamment grands pour contenir des pointeurs), ce qui ne peut pas arriver sur une machine idéalisée.)

Enfin, tout ce que nous avons à faire est de placer ce programme en boucle. La for@Fboucle, combinée à l' -aoption de ligne de commande, parcourt les champs d'entrée standard (la définition par défaut de "champ" se scinde ici sur des espaces). La redoboucle place le programme entier dans une boucle implicite (autre que, commodément, la lecture d'une entrée standard), ce qui entraîne l'exécution répétée du programme dans une boucle, comme requis par la sémantique de la machine I / D.


Nous saluons le retour! Nous n'avons plus besoin de marquer les drapeaux pour les interprètes, mais notez qu'il s'agit de 'Perl avec -a'. codegolf.meta.stackexchange.com/a/14339/9365
Dom Hastings

6

Système Jelly2-Tag , 8 octets

µḢị⁴⁸;Ḋß

Essayez-le en ligne!

J'ai une prime en faveur des langues pratiques, mais je pense que je pourrais tout aussi bien essayer de gagner la tâche initiale alors que j'y étais (car je ne peux pas gagner ma propre prime).

Implémente une variante des systèmes de balises sans état d'arrêt, car elle n'est pas nécessaire pour la complétude de Turing. Les états sont numérotés à partir de 1, consécutivement, et la chaîne initiale précède le programme.

Par exemple, Wikipedia donne un exemple d'un système de balise { a, b, c}, { abc, ba, caaa} avec chaîne initiale aaa; dans ce format d'entrée, qui est [1,1,1], [[2,3],[1],[1,1,1]]. (Les systèmes de balises n'ont pas de syntaxe fixe, et cela semble être un moyen raisonnable de le faire.)

Le lien TIO a un ajout ("write internal state et un newline to stdout") afin de montrer que le programme fonctionne réellement.

Explication

µḢị⁴⁸;Ḋß
           {implicit: initialise internal state from first argument}
µ          Disregard the second command-line argument by default
 Ḣ         Take the first element, removing it from the internal state
  ị⁴       Use the value to index into the second argument
    ⁸;     Prepend (the rest of) the internal state
      Ḋ    Discard the first element of the internal state
       ß   Loop forever

6

BF / P "implémenté dans une machine de Turing, 842 octets

Table de transition (liée en raison de la longueur)

Table de transition, version moins golfée

Simulateur de machine de turing j'ai utilisé

Cela ne va certainement pas gagner de prix pour la longueur, mais c'est quelque chose que j'ai toujours voulu faire, car BF est si similaire à une machine de Turing. Chaque cellule stocke une valeur de 0x0- 0xF. La largeur est cependant loin que le site Web de Turing Machine puisse aller sans bloquer votre navigateur. Les fonctions ,et .(entrée et sortie) ne sont pas définies, donc c'est un peu plus comme P "que vrai BF.

Pour l’exécuter, collez le tableau de transition dans le simulateur de Turing Machine, définissez l’entrée sur du code BF, puis appuyez sur Exécuter.

La bande de la MT stocke à la fois le code BF et les données BF, avec un seul espace au milieu. Il garde une trace de sa position dans le code en modifiant le caractère en cours d’exécution ( [-> (, etc.) et sa position dans les données avec un ^en face de la cellule. Une fois qu’il a lu un caractère de commande, il se déplace jusqu’à atteindre le curseur, déplace d’une cellule à la droite et exécute la fonction appropriée. Ensuite, il retourne en cherchant l'un des caractères de commande "modifiés" dans le code BF et passe au suivant en répétant tout le processus. Une fois qu'il est à court de code, il s'arrête.

Le meilleur moyen de comprendre son fonctionnement consiste à exécuter la version sans golf, à la mettre en mode pas à pas et à regarder quelles lignes mènent à quelles autres et ce que fait chaque état / bloc de lignes.

Les versions golfée et non-golfée sont exactement identiques en ce qui concerne leur fonctionnement, mais la version non-golfée a des noms plus conviviaux et est divisée en sections.


1
La limite de longueur de poste est plus que suffisante pour s'adapter à la table de transition
ASCII uniquement

6

C implémentation de la (2,3) machine de Turing , 236 205 octets ( 46 de moins si vous ne vous souciez pas des entrées fastidieuses)

Merci à Appleshell pour -11 octets, à VisualMelon pour -12 octets et à Johan du Toit pour -7 octets.

CeilingCat a créé une version qui utilise seulement 144 octets, voir ici .

(J'ai ajouté quelques sauts de ligne ici pour que vous n'ayez pas à faire défiler, mais normalement, la plupart d'entre eux seraient supprimés)

#define c char
j;i;k;c s,d[256];c main(){c*p=d+128;gets(d);
for(;k<256&&d[k];)d[k++]-=48;for(;++j<256;)
{c t=*p;*p=-t*t+(2-s)*t+1+s;p+=(s^t==0)*2-1;s=s?t%2:!t%3;
for(i=0;++i<256;)printf("%d",d[i]);puts("");}}

Essayez-le en ligne!

Pour l’utiliser: Entrez une chaîne de 256, zéro et deux au maximum pour initialiser la bande. Toute valeur non initialisée sera zéro. (Des valeurs autres que 0, 1 et 2 peuvent entraîner un comportement indéfini.) Le programme effectuera une itération sur 256 étapes. Le nombre d'étapes sur lesquelles il est itéré peut être augmenté en modifiant le code, mais cela nécessite évidemment plus de caractères.

C'est une assez longue entrée, mais c'est la première fois que je fais l'une de ces choses et je n'ai pas utilisé de langage de golf dédié. Je me suis beaucoup amusé, même si cela a été plus long que prévu.

Un grand nombre d'octets concernent les entrées et les sorties et j'ai perdu 42 octets en le faisant accepter 0, 1 et 2 au lieu de NUL, SOH, STX. (Pour changer cela, supprimez-le k;de l'avant et for(;k<256&&d[k];)d[k++]-=48;de la deuxième ligne.)

La table de transition, en particulier la ligne *p=-t*t+(2-s)*t+1+s;(qui définit les valeurs sur la bande) pourrait probablement être davantage compressée.


1
Wow, et c'est votre premier code de golf ici! Magnifique!
Zacharý

Vous pouvez raccourcir les déclarations de variable globales comme ceci: k,j;c s,d[256];( intest implicite en C, vous pouvez également passer ià la déclaration globale pour économiser 3 octets de plus)
Appleshell

@ Applehell Merci, je vais le faire.
a52

Vous pouvez déplacer la chaîne null-terminal check dans la boucle for. En doublant k++et en supprimant les {}sauvegardes, vous épargnez quelques octets de plus: for(;k<256&d[k];)d[k++]-=-48;Parce qu’il js’agit d’un chronomètre (valeur jamais utilisée), vous pouvez le remplacer (et i) ken comptant à rebours: vous savez k==256après la première boucle, compte à rebours jusqu'à zéro dans la seconde for(;k>0;), qui laisse k==-1, alors la dernière boucle peut devenir for(;++k<256;). (Avertissement: je joue habituellement au golf C#, mais cela a semblé compiler).
VisualMelon

1
@VisualMelon j'ai déterminé le problème. Je devais utiliser k<256&&d[k], pas &, car d[k]était évalué à k==256. De plus, comme kil n'était plus garanti d'être 256après cette boucle, je devais le réinitialiser par la suite afin de garantir 256 étapes. (Si vous (c'est-à-dire VisualMelon) avez d'autres suggestions, nous devrions probablement les mettre en discussion afin d'éviter les commentaires
excessifs

5

Röda implémentant Fractran , 114 112 106 octets

1 octet enregistré grâce à @fergusq en réorganisant les paramètres

f&n,a{x=1{x=0;(a/" ")()|[_/`/`]|[parseInteger(_[0],_1[1])]|{|q,w|{n*=q/w;x=1}if[n%w<1,x<1]}_,_}while[x>0]}

Essayez-le en ligne!

Appelez la fonction comme ceci: f reference_to_input program. La sortie sera stockée à l'emplacement du fichier input.


Le point-virgule après e[1]est redondant. Vous pouvez également enregistrer un octet en changeant l' ordre des paramètres: f&n,a.
fergusq

@fergusq Merci pour le f&n,atour, et j'étais sur le point de supprimer ce point-virgule lorsque vous avez commenté :)
Kritixi Lithos

5

Clojure, 82 81 octets (machine de Turing)

Mise à jour: suppression d'un espace de t{} s.

#(loop[p 0 t{}s 1](if-let[[S M N](%[(or(t p)0)s])](recur(+ p M)(assoc t p S)N)t))

Implémente la machine de Turing en tant que boucle et renvoie la bande lorsque l'état d'arrêt est atteint. Dans les règles de transition d'état, cela est indiqué par la désactivation de l'état de transition. Cette settins Nà nilet la suivante if-letannulerait que la transition d'état correspondant n'a pas été trouvé à partir de l'entrée de hachage carte %. En réalité, toute valeur pour cet état fera l'affaire, telle que :abort0 ou -1.

Ungolfed avec un exemple de castor occupé à 3 états et à 2 symboles de Wikipedia .

(def f #(loop[pos 0 tape {} state 1]
          (if-let [[sym move next-state](%[(get tape pos 0)state])]
            (do (println [pos tape state])
                (recur(+ pos move)(assoc tape pos sym)next-state))
            tape)))

(f {[0 1] [1  1 2]
    [0 2] [1 -1 1]
    [0 3] [1 -1 2] 
    [1 1] [1 -1 3]
    [1 2] [1  1 2]
    [1 3] [1  1]})

{0 1, 1 1, -1 1, -2 1, -3 1, 2 1}

Essayez-le en ligne .

Sur un noyau unique de 6700K, le castor occupé à 5 symboles et à 2 symboles (47,1 millions d'étapes) est exécuté en environ 29 secondes, soit 1,6 million d'étapes / seconde.


5

MAstuce , 4 octets

Ṅ×ịß

Essayez-le en ligne!

Le lien TIO ajoute un pied de page pour appeler la fonction avec l'exemple de programme Tip présenté sur la page Esolang (le "wrapper automatique" de M. pour appeler des fonctions comme s'il s'agissait de programmes qui ne peuvent pas gérer des nombres rationnels ou à virgule fixe, Vous ne savez pas comment le dire, je dois donc transformer la fonction en un programme complet à la main pour pouvoir l’exécuter.)

Cela affiche en fait une sortie de débogage utile. le programme ne peut pas être écrit sur 3 octets en M car un programme composé de trois dyades au moins déclenche un cas particulier dans l'analyseur. Il a donc fallu ajouter une commande supplémentaire pour éviter ce cas particulier. Le faire (imprimer avec une nouvelle ligne) lui donne au moins un but utile.

ıi=1

N'implémente pas d'E / S (autre que stop / no-stop). I / O est une extension de Tip (ne faisant pas partie du langage lui-même) et n'est pas nécessaire pour la complétude de Turing.

Explication / fond

Ṅ×ịß
Ṅ     Print {the left argument} and a newline; also resolves a parser ambiguity
  ị   {The left argument}th element of {the right argument}, wrapping on OoB
 ×    Multiply {the left argument} by {the chosen element}
   ß  Recursive call; arguments: {the product} and {the same right argument}

[1,2,3][1,2,3,1,2,3,1,2,3,…]rx+s, qui est un polynôme, et la "conversion de base" intégrée à de nombreuses langues de golf est en réalité un évaluateur polynomial polyvalent déguisé. Donc, tout ce que nous avons à faire est d’indexer dans une liste de listes de chiffres, de les convertir en base, et nous avons terminé, n’est-ce pas?

xx

x(xy)xy. Bien sûr, nous pourrions remplacer le comportement de chaînage par presque tout ce que nous voulons, mais cela coûterait un octet entier, et les entrées en langage golfique de cette question deviennent si courtes qu’un octet coûte beaucoup.

Alors j'ai regardé en arrière et réévalué un peu. Existe-t-il des opérations que nous pourrions utiliser à la place de l'évaluation polynomiale? Idéalement, ceux qui sont commutatifs, afin que nous n'ayons pas à nous soucier de l'ordre des arguments? Peu de temps après, j'ai compris que les fonctions de Collatz étaient plus complexes que nécessaire.

s

Et bien sûr, contrairement à la conversion de base ( ), multiplication ( ×) est commutative, donc l'ordre dans lequel les arguments sont placés n'a pas d'importance. Il suffit donc d'écrire ×ị, puis de placer le programme dans une récursion infinie avec ß, et nous avons un langage complet de Turing. Droite?

(xy)(xy)¹×ịß¹¹ est un bon choix car il produit une sortie de débogage utile.

Trois octets sont-ils possibles? À moins que je ne manque quelque chose, pas avec ce choix spécifique de langage implémenté et implémenté, mais à ce stade-ci, cela semble sûrement possible, car il y a tant de façons de le faire en quatre et autant de Turing-complete langues que vous pouvez implémenter.


Après avoir réfléchi davantage à cela, nous pourrions réduire ce nombre à trois octets en utilisant et plutôt que ×et ; Le langage qui en résulte n'est pas tout à fait le même langage que Tip, mais il est assez similaire et presque certainement Turing-complete pour la même raison. Malheureusement, ce n'est pas implémenté dans M et je ne trouve aucun moyen de faire en sorte que Jelly fasse des calculs de précision arbitraire lorsque l'une des entrées est un nombre réel non entier. Si quelqu'un connaît d'autres langues de golf où cette construction pourrait fonctionner, n'hésitez pas à tenter le coup.
ais523

4

C interprétant Brainfuck, 187 octets

t[999],*p=t,c,i,l;f(char*t){for(i=0;c=t[i];i++){c^62?c^60?c^43?c^45?c^46?c^44?c^91:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;if(c==93&&*p)for(l=1;l>0;)c=t[--i],c==91?l--:c==93?l++:0;}}

Essayez-le en ligne


3
Welp, il devait y avoir une réponse en utilisant BF.
Zacharý

4

Lua interprétant Brainf ***, 467 octets

b,r,a,i,n,s=0,io.read,{0},1,1,"><+-.,[]"c,f=r(),{function()n=n+1;a[n]=a[n]or 0;end,function()n=n-1;a[n]=a[n]or 0;end,function()a[n]=a[n]+1;end,function()a[n]=a[n]-1;end,function()io.write(string.char(a[n]))end,function()a[n]=io.read():byte()end,function()i=a[n]~=0 and i or c:find("]",i)end,function()if a[n]~=0 then b,x=1,""repeat i=i-1 x=c:sub(i,i)b=x=="["and b-1 or x=="]"and b+1 or b until b==0 and x=="["end end}repeat f[s:find(c:sub(i,i),1,1)]()i=i+1 until i>#c

Je sais qu'il est encore possible de maigrir plus tard, mais voici où ma première passe s'est terminée. Prend le code brainf de l'entrée standard.


2
+1 pour les brains, c'est toujours amusant quand les golfeurs assignent une liste de variables.
Zacharý

4

CJam → variante ResPlicate, 15 14 13 octets

-1 octet grâce à @ ais523

l~{(/((*+e_}h

La variante est la même que celle de cette réponse , à la différence que le nombre d'éléments retirés de la file d'attente est inférieur de un au nombre le plus élevé dans la file d'attente.

La l~{ ... }hpièce prend simplement un tableau en entrée et se répète jusqu'à ce que ce tableau soit vide.

Explication de la boucle principale:

    e# Stack:             | [3 2 1 1 2 2 2 1]
(   e# Pop first element: | [2 1 1 2 2 2 1] 3
/   e# Split chunks:      | [[2 1 1] [2 2 2] [1]]
(   e# Pop first:         | [[2 2 2] [1]] [2 1 1]
(   e# Pop first:         | [[2 2 2] [1]] [1 1] 2
*   e# Repeat array:      | [[2 2 2] [1]] [1 1 1 1]
+   e# Concatenate:       | [[2 2 2] [1] 1 1 1 1]
e_  e# Flatten:           | [2 2 2 1 1 1 1 1]

Vous n'avez pas vraiment besoin de l'incrément ici. Il suffit de spécifier que les longueurs de bloc doivent être incrémentées de 1 dans le programme d'origine; cela ne nuit pas à la complétude de Turing de ResPlicate (il existe des constructions de TC dans lesquelles les longueurs de bloc et les comptages de répétitions ne sont jamais mélangés).

3

Puce , 20 + 3 = 23 octets (règle 110)

AZZ
>}/a
`)\'E~Zte*f

+3 pour le drapeau -z

Essayez-le en ligne!

Cette soumission n’est pas parfaite, car Puce n’a pas (encore) de capacité en boucle. Le résultat doit donc être transmis comme entrée pour simuler plusieurs générations, avec quelque chose comme cela (bien sûr, vous pouvez exécuter cette boucle indéfiniment, et Chip peut gérer des entrées arbitrairement longues, cette combinaison est donc Turing Complete).

Cette implémentation prend en entrée et donne en sortie sous forme ASCII 0s et 1s. La logique est la suivante:

p := value of left neighbor cell    AZZ
q := value of current cell          AZ
r := value of right neighbor cell   A

q' := ((r xor q) and p) or          >}/a
      ((r or q) and ~p)             `)\'

Le reste des éléments est destiné à la gestion interne: e*fprovoque la sortie des chiffres ASCII et E~Zttermine l'exécution deux octets après que l'entrée est épuisée (car la largeur augmente de 2 à chaque génération).


3

Clojure, 75 octets (système de balises cycliques)

Mise à jour 1: remplacé some?par nil?.

Mise à jour 2: Correction d'un élément manquant Sdans la branche else de if s.

#(loop[[p & P](cycle %)[s & S]%2](if(nil? s)S(recur P(if s(concat S p)S))))

Implémente le système de balises cycliques , retourne nilsi le programme s'arrête, boucle pour toujours sinon. Clojure brille vraiment ici avec une infinité de séquences paresseuses (telles que cycle ) et de déstructuration . Les uns et les zéros sont indiqués comme des valeurs vraies et fausses. Lorsque la chaîne de données est épuisée sdevient nil.

Ungolfed:

(def f #(loop[[p & P] (cycle %) [s & S] %2 i 5]
          (do
            (pprint [p (concat [s] S)])
            (if (and (some? s) (pos? i))
              (recur P (if s (concat S p) S) (dec i))))))

Exemple de résultats:

(f [[false]] [true true])
[[false] (true true)]
[[false] (true false)]
[[false] (false false)]
[[false] (false)]
[[false] (nil)]

(f [[false true true] [true false] [true false true]] [true])
[[false true true] (true)]
[[true false]      (false true true)]
[[true false true] (true true)]
[[false true true] (true true false true)]
[[true false]      (true false true false true true)]
[[true false true] (false true false true true true false)]

2

Interprétation JavaScript de la règle 110 , 131 octets (99 octets?, 28 octets?)

a=(p,q,r)=>q+r+q*r+p*q*r
b=l=>{r="";for(i=0;i<l.length-2;i++)r+=a(l[i],+l[i+1],+l[i+2])%2;return r}
c=(l,n)=>!n?l:c(b(0+l+0),n-1)

Comme vous pouvez le constater, le code définit 3 fonctions a, bet c. Peut-être est-il possible de sauvegarder des octets en les combinant dans 1 fonction (je ne vois pas comment), mais il est bon qu’ils se séparent car chacun d’entre eux remplit déjà ce défi dans un sens.

Function aprend 3 nombres en entrée et en calcule un polynôme étrange. Lorsque ces 3 numéros sont 0ou 1peuvent être vus comme des cellules de règle 110. La parité de la sortie de apeut alors être considérée comme la valeur de la cellule du milieu dans la génération suivante. Donc, dans un certain sens, cette fonction simple est déjà un "interprète" de règle 110 (28 octets):

a=(p,q,r)=>(q+r+q*r+p*q*r)%2

Nous pouvons ensuite créer une nouvelle fonction bqui évalue achaque caractère d'une chaîne de uns et de zéros. Il bs’agit alors, dans un meilleur sens que celui d’ aun interprète de la règle 110. Prendre le mod 2 après l’évaluation des sauvegardes entre crochets (99 octets):

a=(p,q,r)=>q+r+q*r+p*q*r
b=l=>{r="";for(i=0;i<l.length-2;i++)r+=a(l[i],+l[i+1],+l[i+2])%2;return r}

Pour calculer réellement une fonction avec la règle 110, l'utilisateur doit spécifier l'état de départ et le nombre de générations après lequel la sortie apparaîtra. Nous pouvons créer une troisième fonction cqui prend une chaîne de uns et de zéros, et un entier positif n, qui évalue ensuite bla chaîne, les ntemps. Ainsi, nous pouvons vraiment considérer la règle 110 comme un langage de programmation, où un programme est un état initial et un nombre n, et la sortie est un état après des ngénérations. La fonction cest maintenant un interpréteur réel pour ce langage de programmation, de sorte que le code final de ce défi est celui que j'ai présenté ci-dessus.


Est-ce que cela calcule 110 avec le fond approprié? Une de mes réponses précédentes avait été supprimée car elle n’avait pas d’arrière-plan.
Wheat Wizard

@WheatWizard l'arrière-plan fait partie de l'entrée, votre réponse n'aurait pas dû être supprimée pour cela
Jens Renders

L'arrière-plan doit être infini, pouvez-vous prendre une entrée infinie?
Wheat Wizard

@WheatWizard ça ne doit pas forcément être infini, ça doit pouvoir être arbitrairement grand, et ça le peut
Jens Renders

1
La règle 110 n’est pas complète si vous décidez de la génération à l’avance et que vous avez besoin d’un apport infini dans la construction que je connais. Même si quelqu'un a trouvé une construction avec un état initial fini, vous ne pouvez pas connaître la mémoire ou le temps nécessaire avant l'exécution du programme, car vous pourriez alors résoudre le problème Halting.
Ørjan Johansen

2

JS -> Newline 854 octets

(function(d){var b=0;var n=!0;var c=[];var h=[];var e=0;var l=[];var m=0;var f=2;var a=0;var g=!1;var k=function(a){if(a===1)return!1;if(a%2===0&&a!==2)return!1;if(a%3===0&&a!==3)return!1;if(a%5===0&&a!==5)return!1;if(a%7===0&&a!==7)return!1;for(var b=7;b<d.round(d.sqrt(a))+1;b++)if(a%b===0)return!1;return f=a,!0;};var j=0;var i=0;var o=function(q){var o=d.__split(q,'\n');d.println(o);for(var n=0;n<o.length;n++)if(n>=f^2&&n<=f+1^2&&k(n)){f=n;for(var p=0;p<o[n].length;p++){if(o[n]==='+'&&(a+=c[b],b++),o[n]==='-')if(g===!0&&a<=0)break;else a-=c[b],b++;if(o[n]==='*'&&(a*=c[b],b++),o[n]==='/'&&(a/=c[b],b++),o[n]==='s'&&(a=d.sqrt(a)),o[n]==='%'&&(a%=c[b],b++),o[n]==='a'&&l.push(a),o[n]==='g'&&(a=c[b],b++),o[n]==='q'&&c.push(a),o[n]==='i'&&a++,o[n]==='d')if(g===!0&&a<=0)break;else a--;o[n]==='r'&&(g=!0),o[n]==='w'&&(g=!1),o[n]==='['&&(j=n),o[n]===']'&&a>0&&(n=j,h[e]--),o[n]==='{'&&(i=n),o[n]==='}'&&h[e]>0&&(n=i,h[e]--),m=a,o[n]==='k'&&e++;}}};});

Super golfé grâce à google.


Je pense que vous avez posté cette réponse au mauvais défi. Vouliez-vous le poster sur ce challenge ?

1
Dans ce cas, vous devez modifier l'implémentation pour viser les différentes conditions de victoire. c'est du code-golf , pas de la popularité-concours . Par exemple, vous avez beaucoup de noms de variables qui pourraient clairement être plus courts, ce qui signifie que cette solution n'est pas un sérieux prétendant. Vous pouvez peut-être le supprimer pour l'instant et le restaurer lorsque vous avez le temps de jouer au golf.

1
Néanmoins, les réponses qui n'essayent pas sérieusement d'optimiser la condition de victoire vont à l'encontre des règles . C'est une raison suffisante pour le supprimer jusqu'à ce que vous puissiez le rendre conforme aux règles.

1
Vous pouvez combiner toutes les vardéclarations:var b=0,n=!0,c=[],h=[],e=0,l=[],m=0,f=2,a=0,g=!1;
Esolanging Fruit

1
Pls supprimer tout varty
ASCII-seulement

1

Clojure, 87 octets (règle 110)

Le code de parité est attribué à Jens Renders! J'avais beaucoup de mal à exprimer cela et j'allais passer à la conversion [p q r]de binaire en entier et utiliser une table de correspondance.

#(iterate(fn[S](for[[p q r](partition 3 1(concat[0]S[0]))](mod(+ q(* q(+ 1 p)r)r)2)))%)

Ici partitionet la déstructuration de Clojure simplifie l'application logique. Cette fonction renvoie une séquence infinie d'états. L'appelant est donc responsable de tous takeles processus dont il a besoin ou juste nthpour passer à un état spécifique. Si les marges avec zéro étaient deux éléments au lieu d'un, la bande se développerait constamment, évitant ainsi les problèmes de limites. Maintenant, il reste la largeur d'origine.

Exemple:

(def f #(iterate(fn[S](for[[p q r](partition 3 1(concat[0]S[0]))](mod(+ q(* q(+ 1 p)r)r)2)))%))

(pprint (take 5 (f '(0 0 0 0 0 1 1 1 0 0 1 0 0))))
((0 0 0 0 0 1 1 1 0 0 1 0 0)
 (0 0 0 0 1 1 0 1 0 1 1 0 0)
 (0 0 0 1 1 1 1 1 1 1 1 0 0)
 (0 0 1 1 0 0 0 0 0 0 1 0 0)
 (0 1 1 1 0 0 0 0 0 1 1 0 0))

1
Si vous travaillez uniquement avec la largeur d'origine, Turing-complete ne peut pas être complet, car il ne dispose que d'un espace de stockage mémoire limité. (En fait, toutes les constructions de complétude de Turing connues à partir de la règle 110 requièrent le "remplissage" utilisé pour agrandir la largeur au fur et à mesure que le programme a un motif spécifié à partir d'une entrée utilisateur, et différent à gauche et à droite, plutôt que juste en utilisant des zéros.)

Je vois que cela rend sa simulation plutôt difficile alors. Clojure cyclepourrait construire le modèle de remplissage infini, mais l'exécution de la première étape prendrait un temps infini: /
NikoNyrh

À bien y penser, il ne serait pas trop difficile de prendre ces motifs de remplissage comme arguments supplémentaires et d’étendre la bande simulée d’un bloc vers la gauche et vers la droite. La vitesse de l'information ici est de 1 bloc / itération, il suffit donc de simuler le "cône de lumière" autour du bloc central qui présente la structure asymétrique. (CMIIW)
NikoNyrh

1

APL (Dyalog) → variante Fractran , 15 octets

(⊃0~⍨××0=1|×)⍣≡

Essayez-le en ligne!

La fonction prend les rationnels sous forme de liste de nombres plutôt que deux listes contenant le numérateur et le dénominateur, et génère le résultat si le programme se termine. Ceci implémente une variante de Fractran qui a le rationnel 1/1 (= 1) à la fin du programme. Le 1 n'a pas d'incidence sur la complétude de Turing (pour autant que je sache), car l'entrée du programme n'atteint le 1 que si aucun des autres raisonnements ne fonctionne et que, dans ce cas, l'entrée n'est pas modifiée. Ceci est uniquement utilisé pour que la fonction sache quand se terminer.

La liaison TIO exécute la fonction pendant 2 itérations (afin que vous puissiez voir la sortie tant que le programme ne se termine pas) sur la première entrée, puis exécute la deuxième entrée jusqu'à la fin, après quoi elle renvoie la sortie.

(⊃0~⍨××0=1|×)⍣≡ prend la liste des rationnels en tant qu'argument de gauche, appelé input, et l'entrée en tant qu'argument de droite,

(⊃0~⍨××0=1|×) train de fonction

  • 1|×obtenir la partie après le point décimal (modulo 1) du produit ×de et

  • 0= est-ce égal à 0?

  • ×× multipliez ce résultat par ⊣ × ⊢, partout où le rationnel × n'est pas un entier, il est remplacé par 0

  • 0~⍨ supprimer tous les 0

  • obtenir le premier élément

boucle tant que l’ entrée n’a pas changé, notez que le résultat de (⊃0~⍨××0=1|×)est réutilisé en tant qu’entrée; ainsi, si elle cesse de changer (à cause du 1 à la fin), le programme s’arrête


1

JavaScript: Calcul lambda ( 123 à 114)

Représenté à l'aide de Debruijn Indicies in Duples.

V=function b(c,d){if(!isNaN(c)){for(;--c;)d=d[1];return d[0]}return 0==c[0]?e=>b(c[1],[e,d]):b(c[0],d)(b(c[1],d))}

Le combinateur S est [0, [0, [0, [[3, 1], [2, 1]]]]]

K est [0, [0, 2]]

Je est [0, 1]

Edit: Rasé 9 octets en remplaçant "number"==typeof cpar!isNaN(c)


0

APL (Dyalog Unicode) , SBCS de 15 octets

Programme complet qui implémente un exécuteur automatisé cellulaire unidimensionnel généralisé. Cela inclut la règle 110 qui est complète à Turing. Invite stdin pour indiquer l'état initial, le nombre d'itérations (ou le maintien jusqu'à la stabilité ou {⍵≡⎕←⍺}d'afficher toutes les valeurs intermédiaires jusqu'à la stabilité) et l'ensemble de règles.

⎕∊⍨∘(⊢∘⊂⌺3)⍣⎕⊢⎕

Essayez-le en ligne! (4 itérations de la règle 110)

 invite pour l'état initial et

 céder cela (sépare l'état du nombre d'itérations)

⍣⎕ demandez le nombre d'itérations et appliquez la fonction suivante plusieurs fois:

() Applique la fonction tacite suivante:

  ⌺3 récupère tous les quartiers de longueur 3 (avec des informations indiquant s'ils sont au bord) et applique la fonction tacite suivante à chaque paire:

    clôturer le quartier

    et

    céder cela

 puis

∊⍨ vérifier s'ils sont membres de

 invite pour la liste des quartiers menant à la prochaine itération

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.