Brainfuck | |
---|---|
Sprog klasse | esoterisk |
Dukkede op i | 1993 |
Forfatter | Urban Muller |
Udvikler | Urban Müller [d] |
Filtypenavn _ | .beller.bf |
Dialekter | BrainSub, Brainfork, Brainloller, COW, Ook, Pbrain, Smallfuck, Spoon , LOLCODE , Whitespace , DoubleFuck , Feckfeck |
Blev påvirket | FALSK |
Mediefiler på Wikimedia Commons |
Brainfuck er et af de esoteriske programmeringssprog , opfundet af Urban Müller i 1993 , kendt for sin minimalisme . Sprogets navn kan oversættes til russisk som hjernefjernelse , det er direkte afledt af det engelske udtryk brainfuck ( brain - brain , fuck - fuck ), altså at engagere sig i nonsens . Sproget har otte kommandoer, som hver er skrevet med et tegn. Kildekoden til et Brainfuck -program er en sekvens af disse tegn uden yderligere syntaks.
Et af Urban Mullers motiver var at skabe et sprog med så lidt compiler som muligt. Det var delvist inspireret af det FALSK sprog , som der var en 1024 byte compiler til. Der er Brainfuck-sprogkompilatorer på mindre end 200 bytes [1] . Programmering på Brainfuck-sproget er svært at skrive, som det nogle gange kaldes sproget for masochister. Men samtidig er Brainfuck et helt naturligt, komplet og enkelt sprog og kan bruges til at definere begrebet beregnelighed .
Maskinen, styret af Brainfuck- kommandoerne , består af et ordnet sæt celler og en pointer til den aktuelle celle, der ligner en Turing-maskines tape og hoved . Derudover indebærer det en enhed til at kommunikere med omverdenen (se kommandoerne . og , ) gennem inputstrømmen og outputstrømmen.
Brainfuck-sproget kan beskrives ved hjælp af C- sprogækvivalenter :
Team Brainfuck | C ækvivalent | Holdbeskrivelse |
---|---|---|
Program start | int i = 0; char arr[30000]; memset(arr, 0, sizeof(arr)); |
hukommelse er allokeret til 30.000 celler med nul begyndelsesværdier |
> | i++; | flytte til næste celle |
< | i--; | flytte til forrige celle |
+ | arr[i]++; | øge værdien i den aktuelle celle med 1 |
- | arr[i]--; | sænk værdien i den aktuelle celle med 1 |
. | putchar(arr[i]); | udskriftsværdi fra den aktuelle celle |
, | arr[i] = getchar(); | indtast en værdi udefra og gem i den aktuelle celle |
[ | while(arr[i]){ | hvis værdien af den aktuelle celle er nul, skal du gå frem i programteksten til tegnet efter det tilsvarende ] (inklusive indlejring) |
] | } | hvis værdien af den aktuelle celle ikke er nul, gå tilbage gennem programteksten til tegnet [ (under hensyntagen til indlejring) |
På trods af ekstern primitivitet har Brainfuck med et uendeligt sæt celler Turing-fuldstændighed , og er derfor ikke ringere end "rigtige" sprog som C , Pascal eller Java med hensyn til potentiale .
Brainfuck er velegnet til eksperimenter i genetisk programmering på grund af syntaksens enkelhed og følgelig generering af kildekode.
I den "klassiske" Brainfuck beskrevet af Muller er cellestørrelsen en byte, antallet af celler er 30.000. I starttilstanden er markøren i positionen længst til venstre, og alle celler er fyldt med nuller. Celleværdier øger eller formindsker modulo 256. Input/output sker også byte for byte, under hensyntagen til ASCII-kodningen (det vil sige, som et resultat af input-operationen ( , ), vil tegnet 1 blive skrevet til den aktuelle celle som tallet 0x31 (49), og outputoperationen ( . ) udført på en celle indeholdende 0x41 (65) vil udskrive det latinske A ). I andre sprogvarianter kan størrelsen og antallet af celler være anderledes (større). Der er versioner, hvor værdien af cellerne ikke er heltal (flydende komma).
I alt 389 sætninger og 1 hukommelsescelle brugt. Det optimerede program er mærkbart kortere - kun 111 udsagn, men 5 hukommelsesceller. Den første celle bruges som en loop-tæller for 10 iterationer, de næste celler indeholder tallene 7, 10, 3 og 1 , øget med denne loop til 70, 100, 30 og 10 , summeringen sker før udskrivning, det andet ord er konstrueret ud fra resterne af den første:
++++++++++ [ > +++++++ > ++++++++++ > +++ > + <<<< - ] > ++ . > + . +++++++ .. +++ . > ++ . << +++++++++++++++ . > . +++ . ------ . -------- . > + . > .Parsing af programmet:
Cyklussen med at fylde de vigtigste tal | |
++++++++++ | tildele celle 0 værdien 10 |
[ | gentag kommandoerne beskrevet i denne parentes, indtil værdien af den aktuelle celle 0 ikke er lig med nul |
>+++++++ | cellestigning 1 gange 7 |
>++++++++++ | cellestigning 2 gange 10 |
>+++ | cellestigning 3 gange 3 |
>+ | cellestigning 4 gange 1 |
<<<<- | celleformindskelse 0 med 1 |
] | kontrollere om celle 0 er nul |
Output af det første ord | |
>++. | i celle 1 , tilføjelse af 2 til 70 og udskrivning af ASCII-koden 72, dvs. bogstaverne " H ". |
>+. | i celle 2 tilføj 1 til 100 = 101, udskriv bogstavet " e " |
+++++++.. | i den samme celle tilføjer 7 til 101 = 108, udskriver " l " to gange |
+++. | i den samme celle tilføjer 3 til 108 = 111, udskriver " o " |
>++. | i celle 3 tilføj 2 til 30 = 32, udskriv et mellemrum |
Andet ord output med celle genbrug | |
<<+++++++++++++++. | i celle 1 tilføj 15 til 72 = 87, udskriv " W " |
>. | celle 2 har allerede 111, udskriv straks " o " |
+++. | i den samme celle tilføjer 3 til 111 = 114, udskriver " r " |
------. | i samme celle, træk 6 fra 114 = 108, udskriv " l " |
--------. | i samme celle, træk 8 fra 108 = 100, udskriv " d " |
>+. | i celle 3 tilføj 1 til 32 = 33, udskriv " ! » |
>. | celle 4 har allerede 10, udskriv straks linjeskift |
Et eksempel på en Brainfuck-tolk skrevet i Perl :
#!/usr/bin/perl åben F , skift ; @code = grep { /[+-\.,\[\]><]/ } split '' , <F> ; for ( min $_ = 0 ; $_ < @code ; ++ $_ ) { ++ $cpu [ $i ] if $code [ $_ ] eq '+' ; -- $cpu [ $i ] if $code [ $_ ] eq '-' ; -- $i if $code [ $_ ] eq '<' ; ++ $i if $code [ $_ ] eq '>' ; udskriv chr $cpu [ $i ] hvis $code [ $_ ] eq '.' ; $cpu [ $i ] = ord <STDIN> hvis $kode [ $_ ] eq ',' ; if ( $kode [ $_ ] eq '[' ) { if ( ! $cpu [ $i ]) { ++ $brc ; while ( $brc ) { ++ $_ ; ++ $brc if $code [ $_ ] eq '[' ; -- $brc if $code [ $_ ] eq ']' ; } } else { næste ; } } elsif ( $kode [ $ ] eq ' ] ' ) { if ( ! $ cpu [ $ i ]) { næste ; } else { ++ $brc if $code [ $_ ] eq ']' ; while ( $brc ) { -- $_ ; -- $brc if $kode [ $_ ] eq '[' ; ++ $brc if $code [ $_ ] eq ']' ; } -- $_ ; } } }Et eksempel på en Brainfuck-tolk skrevet i C++ :
#include <iostream> #include <fstream> #inkluder <vektor> #inkluder <iterator> int main ( int argc , char ** argv ) { std :: fstream fil ( argv [ 1 ], std :: ios :: in ); std :: istreambuf_iterator < char > fstart ( fil ), fend ; std :: vektor < char > itape ( fstart , fend ); fil . lukke (); std :: vektor < char > mtape ( 30000 , 0 ); std :: vektor < char >:: iterator m = mtape . begynde (); std :: vektor < char >:: iterator i = itape . begynde (); int b = 0 ; for (; i != itape . end (); ++ i ) { switch ( * i ){ sag '>' : if ( ++ m == mtape . end ()) { mtape . pushback ( 0 ); m = -mtape . _ ende (); } bryde ; case '<' : -- m ; bryde ; case '+' : ++* m ; bryde ; case '-' : --* m ; bryde ; tilfælde '.' : std :: cout << * m ; bryde ; case ',' : std :: cin >> * m ; bryde ; tilfælde '[' : if ( * m ) fortsætte ; ++ b ; mens ( b ) switch ( *++ i ){ case '[' : ++ b ; bryde ; case ']' : - b ; bryde ; } bryde ; tilfælde ']' : hvis ( !* m ) fortsætter ; ++ b ; mens ( b ) switch ( *-- i ){ case '[' : - b ; bryde ; case ']' : ++ b ; bryde ; } --jeg ; _ bryde ; } } }Enhver Brainfuck- programmeringsbegynder løber straks ind i følgende problemer:
Disse problemer kan løses.
Betegn med @(k) skiftet med k celler til højre hvis k>0, og til venstre hvis k<0 Følgelig @(k) = >… k gange …> eller <… -k gange …<Brainfuck bruges næsten aldrig til praktisk programmering (med undtagelse af individuelle entusiasters arbejde), og bruges hovedsageligt til puslespil og konkurrenceproblemer.
Bemærkninger: 1. Specielt for funktionaliteten af mOO-kommandoen er de interne koder for dens kommandoer [2] indført i COW-sproget , i tabellen er de angivet i en separat kolonne. 2. Et holds fravær angives som fraværende .
Brainfuck | Okay! | KO | COW kode | Beskrivelse |
] | Okay? Okay! | moo | 0 | Slut på cyklus |
< | Okay? OKAY. | mOo | en | Forrige celle |
> | OKAY. Okay? | moO | 2 | Næste celle |
ots. | ots. | mOO | 3 | Udfør værdien i den aktuelle celle som en kommando med den tilsvarende kode fra området 0 - 11; kode 3 forårsager en loop |
ots. | ots. | Moo | fire | Hvis værdien af den aktuelle celle er nul, så indtast den fra tastaturet; hvis værdien af den aktuelle celle ikke er nul, så vis den på skærmen |
- | Okay! Okay! | MOo | 5 | Værdien af den aktuelle celle er reduceret med 1 |
+ | OKAY. OKAY. | MoO | 6 | Værdien af den aktuelle celle øges med 1 |
[ | Okay! Okay? | MO | 7 | Sløjfestart (COW har en funktion - den første kommando i løkken springes over) |
[-] | ots. | OOO | otte | Nulstiller værdien i den aktuelle celle |
ots. | ots. | MMM | 9 | Hvis registret er tomt, kopier værdien af den aktuelle celle ind i det, ellers kopier registrets indhold ind i cellen og ryd registret |
. | Okay! OKAY. | OOM | ti | Viser værdien af den aktuelle celle |
, | OKAY. Okay! | oom | elleve | Forespørg på værdien af den aktuelle celle |
En anden beskrivelse af de mange dialekter af dette sprog kan findes i wiki-leksikonet over esoteriske sprog [3]
Programmeringssprog | |
---|---|
|