Pyke, 5 personnages
0h.CE
Ceci est capable de produire un nombre infiniment grand, de le transformer en chaîne et de l'évaluer ensuite en tant que code Pyke.
Explication du code:
0
- Ajouter 0 à la pile. Ceci est nécessaire pour commencer un numéro
h
- Incrémenter le nombre précédent. En répétant cette opération un nombre de fois arbitraire, vous pouvez créer des nombres infiniment grands. Pyke supporte les bignums tels qu’ils sont écrits en Python, qui les utilise par défaut.
.C
- Transformez un nombre en chaîne en utilisant l'algorithme suivant: ( lien Github )
def to_string(num):
string = ""
while num > 256:
num, new = divmod(num, 256)
string = chr(new) + string
string = chr(num) + string
return string
À ce stade, nous pouvons créer une quantité arbitraire de chaînes et de nombres naturels dans Pyke avec des valeurs arbitraires. Les nombres peuvent être créés sous la forme correspondant à l'expression régulière 0(h)*
et les chaînes peuvent être créées avec 0(h)*.C
. Ils peuvent être imbriqués les uns dans les autres pour créer un mélange arbitraire de chaînes et de nombres entiers.
E
- évalue une chaîne en tant que code Pyke. Cela utilise le même environnement que le code Pyke en cours d’exécution, ce qui permet de partager des éléments tels que l’entrée.
Tentative de preuve que Pyke est Turing Complete.
Une des manières les plus simples de montrer qu'une langue est complète est d'y implémenter Brainf * ck. C’est probablement beaucoup plus difficile dans Pyke que dans beaucoup d’autres langues, car ses opérations de liste et de dictionnaire sont pratiquement inexistantes en raison du manque de ressources dans la région où Pyke est conçu pour fonctionner: code-golf .
Tout d'abord, nous créons un interpréteur pour brainf * ck et l'encodons à l'aide de notre algorithme ci-dessus pour créer un nombre, puis exprimons ce nombre avec 0
et h
. Nous créons ensuite la chaîne contenant le code à exécuter de la même manière. Si nous devions en rester là, nous aurions la pile comme
string containing brainf*ck code
string containing brainf*ck interpreter
Cela signifie que le code doit être dans la forme opposée car la pile Pyke est du premier entré dernier sorti.
Passons maintenant à la partie amusante: l'interpréteur brainf * ck avec 216 octets!
Q~B"><ht.,".:=B;Z]1=L;W~Bo@D=c"ht"{I~c~LZ@EZ]1~LR3:=L)~c\,qIz.oZ]1~LR3:=L)~c\.qI~LZ@.CpK)~c"<>"{I~c"<>""th".:ZE=ZZ1_qI0=Z~L0"":0]10:=L)Z~LlqI~L~Ll"":1_]10:=L))~c\[qI~LZ@0qI\]~B~o>@~o+h=o))~c\]qI~o\[~B~o<_@-t=o)~o~BlN
Essayez-le ici!
Si vous voulez essayer le code sous une forme semi-complète mais modifiable, essayez-le ici!
Pour convertir une chaîne en un nombre, vous pouvez utiliser le code Python suivant:
def conv(string, t=0):
t *= 256
t += ord(string[0])
if len(string) != 1:
return conv(string[1:], t)
return t
La solution (presque) finale peut être essayée ici!
Explication de l'interprète Brainf * ck
Tout d’abord, séparons le programme en plusieurs parties:
Un séjour sans faille
Q~B"><ht.,".:=B;Z]1=L; - The initialisation part
Q~B"><ht.,".: - input.replace("><+-.,[]", "><ht.,")
- replace the characters in brainf*ck with some modified ones.
- this means we can `eval` the add and subtract bits easily.
=B; - set `B` to this.
- The `B` variable contains the instructions
Z]1=L; - set `L` to [0]
- `L` contains the stack, initialised with 0
Un séjour sans faille
W~Bo@D=c !code! ~o~BlN - The main loop
W - do
~Bo@D=c - c=B[o++]
- the c variable is used to store the current character.
~o~BlN - while
~o - o
N - ^ != V
~Bl - len(B)
- this stops the program running once it's finished.
- Les instructions
- Incrémenter / décrémenter:
+-
Un séjour sans faille
"ht"{I~c~LZ@EZ]1~LR3:=L) - The bit that does incrementing and decrementing
"ht"{I ) - if c in "ht"
~LZ@ - L[Z]
- `Z` contains the current stack pointer
~c E - eval current character with ^ as an argument
- returns the contents of `Z` either incremented or decremented
Z]1~LR3:=L - L[Z] = ^
Un séjour sans faille
~c\,qIz.oZ]1~LR3:=L) - The code for output
~c\,qI ) - if character == ",":
z.o - ord(input)
Z]1~LR3:=L - L[Z] = ^
Un séjour sans faille
~c\.qI~LZ@.CpK) - The code for input
~c\.qI ) - if c == ".":
~LZ@ - L[Z]
.C - chr(^)
pK - print(^)
- Décalage Gauche / Droite
<>
:
Un séjour sans faille
~c"<>"{I~c"<>""th".:ZE=Z - main part
~c"<>"{I - if "<>" in c:
~c"<>""th".: - c.replace("<>", "th")
ZE=Z - Z = eval(char, Z)
Z1_qI0=Z~L0"":0]10:=L) - lower bound check
Z1_qI ) - if Z == -1:
0=Z - Z = 0
~L0"": - L.insert("", 0)
0]10:=L - L[0] = 0
Z~LlqI~L~Ll"":1_]10:=L) - upper bound check
Z~LlqI ) - if Z == len(L):
~Ll"": - L.insert("", len(L))
~L 1_]10:=L - L[-1] = 0
Un séjour sans faille
~c\[qI~LZ@0qI\]~B~o>@~o+h=o)) - Code for `[`
~c\[qI ) - if c == "[":
~LZ@0qI ) - if L[Z] == 0:
~B~o> - B[o:]
\] @ - ^.find("]")
~o+h=o - o = o + ^ + 1
- Et ]
:
Un séjour sans faille
~c\]qI~o\[~B~o<_@-t=o) - Code for `]`
~c\]qI ) - if c == "]":
~B~o<_ - reversed(B[:o])
\[ @ - ^.find("[")
~o -t=o - o = o - ^ -1