Alguien me envió esto y afirmó que es un hola mundo en Brainfuck (y eso espero ...)
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Sé lo básico que funciona moviendo un puntero e incrementando y disminuyendo cosas ...
Sin embargo, todavía quiero saber, ¿cómo funciona realmente? ¿Cómo imprime algo en la pantalla en primer lugar? ¿Cómo codifica el texto? No entiendo en absoluto...
brainfuck
esoteric-languages
deslizador
fuente
fuente
Respuestas:
1. Conceptos básicos
Para entender Brainfuck debes imaginar una variedad infinita de celdas inicializadas por
0
cada una.Cuando se inicia el programa Brainfuck, apunta a cualquier celda.
Si mueve el puntero hacia la derecha,
>
lo está moviendo de la celda X a la celda X + 1Si aumenta el valor de la celda
+
, obtiene:Si vuelve a aumentar el valor de la celda
+
, obtiene:Si disminuye el valor de la celda
-
, obtiene:Si mueve el puntero hacia la izquierda
<
, está moviendo el puntero de la celda X a la celda X-12. Entrada
Para leer el carácter se usa la coma
,
. Lo que hace es: lee el carácter de la entrada estándar y escribe su código ASCII decimal en la celda real.Eche un vistazo a la tabla ASCII . Por ejemplo, el código decimal de
!
es33
, mientras quea
es97
.Bueno, imaginemos que la memoria de su programa BF se ve así:
Suponiendo que la entrada estándar significa
a
, si usa el,
operador de coma , lo que hace BF es leera
el código ASCII decimal97
en la memoria:Generalmente quieres pensar de esa manera, sin embargo, la verdad es un poco más compleja. La verdad es que BF no lee un carácter sino un byte (cualquiera que sea ese byte). Déjame mostrarte un ejemplo:
En linux
huellas dactilares:
que es un carácter polaco específico. Este carácter no está codificado por codificación ASCII. En este caso, es la codificación UTF-8, por lo que solía ocupar más de un byte en la memoria de la computadora. Podemos probarlo haciendo un volcado hexadecimal:
que muestra:
Los ceros están compensados.
82
es el primero y elc5
segundo byte que representał
(en el orden en que los leemos).|..|
es una representación gráfica que no es posible en este caso.Bueno, si pasa
ł
como entrada a su programa BF que lee un solo byte, la memoria del programa se verá así:¿Por qué
197
? Bueno,197
decimal esc5
hexadecimal. ¿Te parece familiar? Por supuesto. Es el primer byte deł
!3. Salida
Para imprimir el carácter se usa el punto.
.
Lo que hace es: Suponiendo que tratamos el valor real de la celda como un código ASCII decimal, imprime el carácter correspondiente en la salida estándar.Bueno, imaginemos que la memoria de su programa BF se ve así:
Si usa el operador de punto (.) Ahora, lo que hace BF es imprimir:
Porque
a
el código decimal en ASCII es97
.Entonces, por ejemplo, un programa BF como este (97 más 2 puntos):
Aumentará el valor de la celda a la que apunta hasta 97 y lo imprimirá 2 veces.
4. Bucles
En BF, el bucle consta de un comienzo
[
y un final de bucle]
. Puede pensar que es como en C / C ++, donde la condición es el valor real de la celda.Eche un vistazo al programa BF a continuación:
++
incrementa el valor real de la celda dos veces:Y
[]
es comowhile(2) {}
, entonces es un bucle infinito.Digamos que no queremos que este bucle sea infinito. Podemos hacer por ejemplo:
Entonces, cada vez que un bucle se repite, disminuye el valor real de la celda. Una vez que el valor real de la celda
0
finaliza el ciclo:Consideremos otro ejemplo de bucle finito:
Este ejemplo muestra que no hemos terminado el ciclo en la celda en la que comenzó el ciclo:
Sin embargo, es una buena práctica terminar donde comenzamos. Por qué ? Porque si el bucle termina otra celda que comenzó, no podemos asumir dónde estará el puntero de la celda. Para ser honesto, esta práctica hace que la cogida de cerebro sea menos cogida de cerebro.
fuente
Wikipedia tiene una versión comentada del código.
Para responder a sus preguntas, el
,
y.
caracteres se utilizan para E / S. El texto es ASCII.El artículo de Wikipedia también continúa con más profundidad.
fuente
,
y.
se usa para E / S, al igual que C imprime usandoputchar
. Es un detalle de implementación manejado por el compilador.Para responder a la pregunta de cómo sabe qué imprimir, agregué el cálculo de los valores ASCII a la derecha del código donde ocurre la impresión:
fuente
Brainfuck igual que su nombre. Utiliza solo 8 caracteres,
> [ . ] , - +
lo que lo convierte en el lenguaje de programación más rápido de aprender, pero el más difícil de implementar y comprender. … .Y hace que finalmente termines jodiendo tu cerebro.Almacena valores en una matriz: [72] [101] [108] [111]
let, inicialmente puntero apuntando a la celda 1 de la matriz:
>
mover el puntero a la derecha en 1<
mover el puntero a la izquierda en 1+
incrementar el valor de la celda en 1-
incrementar el valor del elemento en 1.
imprimir el valor de la celda actual.,
llevar entrada a la celda actual.[ ]
bucle, +++ [-] contador de 3 cuentas porque tiene 3 ′ + 'antes, y - disminuye la variable de cuenta en 1 valor.los valores almacenados en las celdas son valores ascii:
así que refiriéndose a la matriz anterior: [72] [101] [108] [108] [111] si coincide con los valores ascii, encontrará que es Hello Writtern
¡Felicidades! has aprendido la sintaxis de BF
——- Algo más ———
permítanos crear nuestro primer programa, es decir, Hello World , después del cual podrá escribir su nombre en este idioma.
rompiendo en pedazos:
Hace una matriz de 4 celdas (número de>) y establece un contador de 10 algo como: —- código de psuedo—-
porque el valor del contador se almacena en la celda 0 y> se mueve a la celda 1 actualiza su valor por + 7> se mueve a la celda 2 incrementa 10 a su valor anterior y así sucesivamente….
<<<
vuelve a la celda 0 y disminuye su valor en 1por lo tanto, después de completar el ciclo, tenemos una matriz: [70,100,30,10]
se mueve al primer elemento e incrementa su valor en 2 (dos '+') y luego imprime el carácter ('.') con ese valor ascii. es decir, por ejemplo en python: chr (70 + 2) # imprime 'H'
se mueve al incremento de la 2da celda 1 a su valor 100 + 1 e imprime ('.') su valor es decir, chr (101) chr (101) # imprime 'e' ahora no hay> o <en la siguiente pieza, por lo que toma el valor actual del último elemento e incrementarlo solo
último elemento = 101 por lo tanto, 101 + 7 y lo imprime dos veces (ya que hay dos '..') chr (108) #prints l dos veces se puede usar como
——— ¿Dónde se usa? ——-
Es solo un lenguaje de broma creado para desafiar a los programadores y no se usa prácticamente en ningún lado.
fuente
Todas las respuestas son completas, pero les falta un pequeño detalle: la impresión. Al construir tu traductor de brainfuck, también consideras el personaje
.
, así es como se ve una declaración impresa en Brainfuck. Entonces, lo que debe hacer su traductor de mierda de cerebro es, cada vez que encuentra un.
carácter, imprime el byte apuntado actualmente.Ejemplo:
suponga que tiene ->
char *ptr = [0] [0] [0] [97] [0]
... si esta es una declaración de mierda:>>>.
su puntero debe moverse 3 espacios hacia el aterrizaje derecho en:,[97]
así que ahora*ptr = 97
, después de hacer eso, su traductor encuentra a.
, debe llamaro cualquier declaración de impresión equivalente para imprimir el byte apuntado actualmente, que tiene el valor 97 y la letra
a
se imprimirá en elstd_output
.fuente
Creo que lo que estás preguntando es cómo sabe Brainfuck qué hacer con todo el código. Hay un analizador escrito en un lenguaje de nivel superior como Python para interpretar lo que significa un punto, o lo que significa un signo de suma en el código.
Entonces, el analizador leerá su código línea por línea y dirá que está bien, hay un símbolo>, así que tengo que avanzar la ubicación de la memoria, el código es simplemente, if (contenido en esa ubicación de memoria) ==>, memlocation = + memlocation que es escrito en un lenguaje de nivel superior, de manera similar si (contenido en la ubicación de la memoria) == ".", luego imprime (contenido de la ubicación de la memoria).
Espero que esto lo aclare. tc
fuente