Brainfuck Contingut Disseny Exemples Implementacions Menú de navegacióEtiquetaBFFAlso Written In Brainfuck (awib)Brainfucked
Llenguatges de programació esotèrics
llenguatge de programació esotèricTuring completUrban MüllerAmigaAmiNet1993compiladorbytesbytepunterteclatmonitorASCIIsecció Brainfuck d'Hola món
Brainfuck
Salta a la navegació
Salta a la cerca
Tipus | llenguatge de programació esotèric, turing tarpit i llenguatge de programació |
---|---|
Data de creació | 1993 |
Desenvolupador | Urban Müller |
Epònim | cervell i fuck |
Influenciat per | P′′ i FALSE |
Extensió dels fitxers | b i bf |
Etiqueta d'Stack Exchange | Etiqueta |
Brainfuck és un llenguatge de programació esotèric. Es distingeix pel baix nombre d'instruccions que fa servir, només en té 8. No obstant això és Turing complet.
Contingut
1 Disseny
1.1 Instruccions
1.2 Traducció a llenguatge C
2 Exemples
2.1 Trivials
2.1.1 Netejar posició
2.1.2 Bucle simple
2.1.3 Movent el punter
2.1.4 Afegir
2.1.5 Instruccions condicionals
2.1.6 Copiant un byte
2.2 No trivials
2.2.1 Hola Món!
2.2.2 Suma
2.2.3 Multiplicació
2.2.4 Divisió
3 Implementacions
Disseny
Urban Müller, famós per gestionar la major col·lecció de programari lliure pel Amiga i per a qualsevol sistema informàtic (incloent Unix i Windows) en aquell moment anomenada AmiNet, una mica com una broma, va crear brainfuck el 1993 amb la intenció de dissenyar un llenguatge que pogués ser implementat amb el compilador més petit possible. Es va inspirar en el compilador de 1024 bytes pel llenguatge FALSE. Existeixen diversos compiladors de brainfuck més petits que 200 bytes.
El llenguatge consisteix de 8 instruccions. Un programa de brainfuck és una seqüència d'aquestes instruccions, possiblement intercalades amb altres caràcters (que són ignorats). Les instruccions s'executen seqüencialment, excepte les dues de salt condicional.
El llenguatge es basa en un model d'execució simple que consisteix, a més del programa en una llista de 30.000 posicions, d'un byte de grandària cadascuna, inicialitzades a zero; un punter mòbil a la llista (inicialitzat a la primera posició, a l'esquerra), i dos 'streams' de bytes per entrada/sortida (sovint connectats al teclat i al monitor respectivament, i fent servir ASCII per codificar els caràcters).
Instruccions
Les 8 instruccions del llenguatge, cada una consistint en un simple caràcter, són les següents:
Caràcter | Significat |
---|---|
> | incrementar el punter (per apuntar a la següent posició de la llista, a la dreta). |
< | decrementar el punter (per apuntar a la següent posició de la llista, a l'esquerra). |
+ | increment (incrementar per 1) el byte on apunta el punter. |
- | decrement (decrementar per 1) el byte on apunta el punter. |
. | fer sortir el valor del byte a la posició del punter. |
, | acceptar un byte d'entrada, desant el seu valor al byte on sigui el punter. |
[ | salta l'execució a la instrucció posterior al corresponent ] si el byte del punter és zero. |
] | salta a la instrucció posterior al corresponent [ si el byte del punter no és zero. |
Traducció a llenguatge C
Els programes de brainfuck es poden traduir al llenguatge de programació C fent servir les següents substitucions, assumint que ptr
és de tipus unsigned char*
i ha estat inicialitzat per apuntar a una llista de bytes inicialitzats a zero:
instrucció brainfuck | equivalent C |
---|---|
> | ++ptr; |
< | --ptr; |
+ | ++*ptr; |
- | --*ptr; |
. | putchar(*ptr); |
, | *ptr=getchar(); |
[ | while (*ptr) |
] |
|
Exemples
Trivials
Netejar posició
[-]
Aquesta simple porció de programa neteja la posició actual a zero, iterativament decrementa el seu valor fins que és zero, llavors surt del bucle i continua l'execució.
Bucle simple
,[.,]
Això és un bucle continu, pren text d'entrada (del teclat) i el copia a la sortida (la pantalla). Modifica la posició actual del punter. Només surt quan el valor ASCII zero entra pel teclat.
Aquesta versió fa el mateix però surt quan es prem 'enter' (ASCII 10) al teclat:
,----------[++++++++++.,----------]
Movent el punter
>,[.>,]
Una versió de l'anterior que mou el punter cada cop per desar tot el text entrat a la llista per ús futur.
Afegir
[->+<]
Això afegeix la posició actual (destructivament, la deixa a zero) a la propera.
Instruccions condicionals
,----------[----------------------.,----------]
Aquest codi converteix el text entrat en minúscules pel teclat, el converteix en majúscules i el mostra a la pantalla en prémer la tecla 'enter'.
Primer el caràcter entra fent servir el codi ,
i immediatament es resta 10 (La majoria d'implementacions de brainfuck, si no totes, fan servir 10 pel retorn) Si l'usuari ha premut 'enter' la instrucció condicional [
saltarà a la posició just després de ]
perquè haurem tornat el primer byte a zero. El programa acabarà. Si el primer caràcter no era 'enter' assumim que és una minúscula i li restem 22, per un total de 32, que és la diferència entre una minúscula i la seva respectiva majúscula en ASCII.
Després mostrem per pantalla .
i fem entrar el proper caràcter ,
restant-li 10 un altre cop, si no era 10 anirem a la primera posició del bucle i restarem altre cop 22. El programa acaba en prémer 'enter' perquè no hi ha més instruccions després.
Copiant un byte
(A partir d'aquest punt ens referirem als bytes de la llista com a [0], [1], [2]... successivament)
Brainfuck no inclou una instrucció per copiar bytes. Això ha de fer-se amb les instruccions de bucle. Moure un byte és simple si la destinació és zero (sempre ho és en iniciar el programa) però la posició inicial es perd, com hem vist abans. Així movem [0] a [1]:
[->+<]
Podríem restituir el valor de [0] si l'haguéssim copiat a dues posicions a la vegada. Per copiar [0] a [1] i [2] a la vegada faríem:
[->+>+<<]
Ara podem aprofitar això per restituir [0]. En resum, per copiar [0] a [1] fent servir [2] com espai de treball fem:
[->+>+<<]>>[-<<+>>]<<
No trivials
Hola Món!
Vegeu la secció Brainfuck d'Hola món
Suma
,>++++++[<-------->-],[<+>-],<.>.
Aquest programa suma dos nombres d'un sol dígit i el resultat només és correcte si també té un sol dígit:
entrada: 43'enter'
sortida: 7
El primer nombre entra a [0] i li restem 48 per corregir-lo (ha entrat el codi ASCII, i aquests codis per als dígits 0-9 són 48-57). Això ho fem escrivint 6 en [1] i fent servir el primer bucle per restar-li 8 a [0] 6 cops (Aquest és el mètode normal per sumar o restar nombres llargs.). Després, el segon nombre entra en [1].
El proper bucle [<+>-]
mou el segon nombre al primer tot afegint-los, i posat [1] a zero. En cada volta afegeix 1 a [0] i resta 1 a [1], quan [1] és zero el bucle surt. Després un 'enter' entra a [1].
Es mou el punter altra volta a la posició [0] i es mostra el resultat ([0] és ara a + b + 48 donat que no s'ha corregit b). Es mou el punter a [1] que tenia el 'enter' i es fa sortir, el programa acaba.
Multiplicació
,>,>++++++++[<------<------>>-]
<<[>[>+>+<<-]>>[<<+>>-]<<<-]
>>>++++++[<++++++++>-],<.>.
Igual que el programa anterior, però en comptes de sumar multiplica. Té les mateixes limitacions: 1 dígit per cada valor i resultats d'un dígit.
El primer nombre entra a [0], el segon a [1], es corregeixen tots dos restant-los 48 (primera línia).
Ara s'entra al bucle principal de la multiplicació. La idea bàsica és que cada cop que el programa hi passa restarà 1 a [0] i afegirà el valor de [1] al total que estarà a [2]. En detall: el primer bucle interior mou [1] a [2] i [3] i deixa [1] a zero (La manera bàsica de duplicar un nombre). El següent bucle intern mou [3] un altre cop a [1], deixant [3] a zero. Llavors es resta 1 de [0], i acaba el bucle exterior. En sortir [0] és zero, [1] encara té el segon nombre i [2] té el producte dels dos nombres inicials.
A la tercera línia afegim 48 al producte, s'introdueix un 'enter' en [3], surt el producte en ASCII i després el retorn que havia entrat en [3].
Divisió
,>,>++++++[-<--------<-------->>] entren 2 nombres a (0) i (1) i restem 48 als dos
<<[ bucle fins que el dividend sigui zero
>[->+>+<<] el divisor es mou de (1) a (2) i (3), posant (1) a zero
>[-<<- resta 1 al dividend(0) i al divisor(2) fins que (2) sigui zero
[>]>>>[<[>>>-<<<[-]]>>]<<] si el dividend és zero, sortir del bucle
>>>+ afegir 1 al quocient en (5)
<<[-<<+>>] es mou el divisor de (3) a (2)
<<<] el punter es mou a (0) i es repeteix el bucle
>[-]>>>>[-<<<<<+>>>>>] el quocient en (5) es mou a (0)
<<<<++++++[-<++++++++>]<. afegir 48 i mostrar el resultat
>>>>>>++++++++++. surt 'enter' al final
Quan l'usuari entra dos nombres, aquest codi els divideix, ignorant la resta, i mostra el quocient a la pantalla.
Implementacions
BFF(anglès) intèrpret optimitzat escrit en C portable
Also Written In Brainfuck (awib)(anglès) compilador escrit en brainfuck per GNU/Linux en i386.
Brainfucked(anglès) compilador amb validació de sintaxi i optimització per Microsoft Windows/DOS
Categoria:
- Llenguatges de programació esotèrics
(RLQ=window.RLQ||[]).push(function()mw.config.set("wgPageParseReport":"limitreport":"cputime":"0.152","walltime":"0.209","ppvisitednodes":"value":427,"limit":1000000,"ppgeneratednodes":"value":0,"limit":1500000,"postexpandincludesize":"value":6443,"limit":2097152,"templateargumentsize":"value":38,"limit":2097152,"expansiondepth":"value":9,"limit":40,"expensivefunctioncount":"value":0,"limit":500,"unstrip-depth":"value":0,"limit":20,"unstrip-size":"value":54,"limit":5000000,"entityaccesscount":"value":1,"limit":400,"timingprofile":["100.00% 159.943 1 -total"," 96.79% 154.812 1 Plantilla:Infotaula_llenguatge_programació"," 94.66% 151.409 1 Plantilla:Infotaula"," 7.71% 12.327 1 Plantilla:If_empty"," 6.42% 10.273 3 Plantilla:Colors_infotaules"," 4.18% 6.693 1 Plantilla:Títol_sense_cua"," 2.95% 4.723 3 Plantilla:En"," 1.32% 2.112 1 Plantilla:Indicació_d'idioma"],"scribunto":"limitreport-timeusage":"value":"0.066","limit":"10.000","limitreport-memusage":"value":2133756,"limit":52428800,"cachereport":"origin":"mw1318","timestamp":"20190830210732","ttl":2592000,"transientcontent":false););"@context":"https://schema.org","@type":"Article","name":"Brainfuck","url":"https://ca.wikipedia.org/wiki/Brainfuck","sameAs":"http://www.wikidata.org/entity/Q244627","mainEntity":"http://www.wikidata.org/entity/Q244627","author":"@type":"Organization","name":"Contributors to Wikimedia projects","publisher":"@type":"Organization","name":"Wikimedia Foundation, Inc.","logo":"@type":"ImageObject","url":"https://www.wikimedia.org/static/images/wmf-hor-googpub.png","datePublished":"2006-01-27T15:14:53Z","dateModified":"2017-07-04T21:28:58Z","image":"https://upload.wikimedia.org/wikipedia/commons/b/b4/Hello_World_Brainfuck.png","headline":"llenguatge de programaciu00f3"(RLQ=window.RLQ||[]).push(function()mw.config.set("wgBackendResponseTime":139,"wgHostname":"mw1272"););