Pyke, 5 personajes
0h.CE
Esto es capaz de producir un número infinitamente grande, convertirlo en una cadena y luego evaluarlo como código Pyke.
Explicación del código:
0
- Agregue 0 a la pila. Esto es necesario para comenzar un número
h
- Incremente el número antes. Al repetir esto una cantidad arbitraria de veces, puede crear números que son infinitamente grandes. Pyke admite bignums tal como está escrito en Python, que los usa de forma predeterminada.
.C
- Convierta un número en una cadena usando el siguiente algoritmo: ( enlace Github )
def to_string(num):
string = ""
while num > 256:
num, new = divmod(num, 256)
string = chr(new) + string
string = chr(num) + string
return string
En este punto, podemos crear una cantidad arbitraria de cadenas y números naturales en Pyke con valores arbitrarios. Se pueden crear números en la forma correspondiente a la expresión regular 0(h)*
y se pueden crear cadenas con 0(h)*.C
. Se pueden entrelazar entre sí para crear una mezcla arbitraria de cadenas y enteros.
E
- evaluar una cadena como código Pyke. Esto usa el mismo entorno que el código Pyke que ya se está ejecutando, por lo que compartirá cosas como la entrada.
Intento de prueba de que Pyke está Turing completo.
Una de las formas más simples de mostrar un idioma es completarlo implementando Brainf * ck en él. Esto es probablemente mucho más difícil en Pyke que en muchos otros idiomas porque sus operaciones de lista y diccionario son prácticamente inexistentes debido a la falta de necesidad en el área en la que Pyke está diseñado para ejecutarse: code-golf .
Primero creamos un intérprete para brainf * ck y lo codificamos utilizando nuestro algoritmo anterior para crear un número y luego expresar ese número con 0
y h
. Luego creamos la cadena que contiene el código que se ejecutará exactamente de la misma manera. Si lo dejáramos así, tendríamos la pila como
string containing brainf*ck code
string containing brainf*ck interpreter
Esto significa que el código tiene que estar en la forma opuesta ya que la pila Pyke es la primera en entrar y la última en salir.
Ahora para la parte divertida: ¡el intérprete brainf * ck con la friolera de 216 bytes!
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
Pruébalo aquí!
Si desea probar el código en forma semi-completa pero editable, ¡ pruébelo aquí!
Para convertir una cadena en un número, puede usar el siguiente código de Python:
def conv(string, t=0):
t *= 256
t += ord(string[0])
if len(string) != 1:
return conv(string[1:], t)
return t
¡La (casi) solución final se puede probar aquí!
Explicación del intérprete Brainf * ck
Primero separemos el programa en partes:
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
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.
- Las instrucciones
- De incremento / reducción:
+-
"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] = ^
~c\,qIz.oZ]1~LR3:=L) - The code for output
~c\,qI ) - if character == ",":
z.o - ord(input)
Z]1~LR3:=L - L[Z] = ^
~c\.qI~LZ@.CpK) - The code for input
~c\.qI ) - if c == ".":
~LZ@ - L[Z]
.C - chr(^)
pK - print(^)
- Desplazar a la izquierda / derecha
<>
:
~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
~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
- Y ]
:
~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