Brainfuck | |
---|---|
Språkklass | esoterisk |
Framträdde i | 1993 |
Författare | Urban Muller |
Utvecklaren | Urban Müller [d] |
Filtillägg _ | .beller.bf |
Dialekter | BrainSub, Brainfork, Brainloller, COW, Ook, Pbrain, Smallfuck, Spoon , LOLCODE , Whitespace , DoubleFuck , Feckfeck |
Blivit påverkad | FALSK |
Mediafiler på Wikimedia Commons |
Brainfuck är ett av de esoteriska programmeringsspråken , uppfann av Urban Müller 1993 , känt för sin minimalism . Språkets namn kan översättas till ryska som brain removal , det härstammar direkt från det engelska uttrycket brainfuck ( hjärna - hjärna, fan - fuck ), alltså att ägna sig åt nonsens . Språket har åtta kommandon, som vart och ett är skrivet med ett tecken. Källkoden för ett Brainfuck -program är en sekvens av dessa tecken utan ytterligare syntax.
Ett av Urban Mullers motiv var att skapa ett språk med så lite kompilator som möjligt. Det var delvis inspirerat av det FALSKA språket , för vilket det fanns en kompilator på 1024 byte. Det finns Brainfuck-språkkompilatorer som är mindre än 200 byte [1] . Programmering på Brainfuck-språket är svårt att skriva, för vilket det ibland kallas språket för masochister. Men samtidigt är Brainfuck ett helt naturligt, komplett och enkelt språk och kan användas för att definiera begreppet beräkningsbarhet .
Maskinen, som styrs av Brainfuck- kommandona , består av en ordnad uppsättning celler och en pekare till den aktuella cellen, som liknar en Turing-maskins tejp och huvud . Dessutom innebär det en enhet för att kommunicera med omvärlden (se kommandona . och , ) genom ingångsströmmen och utströmmen.
Brainfuck-språket kan beskrivas med C- språkekvivalenter :
Team Brainfuck | C ekvivalent | Teambeskrivning |
---|---|---|
Programstart | int i = 0; char arr[30000]; memset(arr, 0, sizeof(arr)); |
minne tilldelas för 30 000 celler med noll initialvärden |
> | i++; | flytta till nästa cell |
< | i--; | flytta till föregående cell |
+ | arr[i]++; | öka värdet i den aktuella cellen med 1 |
- | arr[i]--; | minska värdet i den aktuella cellen med 1 |
. | putchar(arr[i]); | utskriftsvärde från aktuell cell |
, | arr[i] = getchar(); | ange ett värde utifrån och lagra i den aktuella cellen |
[ | while(arr[i]){ | om värdet på den aktuella cellen är noll, gå framåt i programtexten till tecknet efter motsvarande ] (inklusive kapsling) |
] | } | om värdet på den aktuella cellen inte är noll, gå tillbaka genom programtexten till tecknet [ (med hänsyn till kapsling) |
Trots yttre primitivitet har Brainfuck med en oändlig uppsättning celler Turing-fullständighet , och är därför inte sämre än "riktiga" språk som C , Pascal eller Java när det gäller potential .
Brainfuck är lämplig för experiment i genetisk programmering på grund av syntaxens enkelhet och följaktligen genereringen av källkod.
I den "klassiska" Brainfuck som beskrivs av Muller är cellstorleken en byte, antalet celler är 30 000. I initialtillståndet är pekaren längst till vänster och alla celler är fyllda med nollor. Cellvärden ökar eller minskar modulo 256. Inmatning/utdata sker också byte för byte, med hänsyn tagen till ASCII-kodningen (det vill säga som ett resultat av inmatningsoperationen ( , ), kommer tecknet 1 att skrivas till den aktuella cellen som talet 0x31 (49), och utmatningsoperationen ( . ) som utförs på en cell som innehåller 0x41 (65) kommer att skriva ut det latinska A ). I andra språkvarianter kan storleken och antalet celler vara olika (större). Det finns versioner där värdet på cellerna inte är heltal (flytande komma).
Totalt 389 satser och 1 minnescell används. Det optimerade programmet är märkbart kortare - bara 111 satser, men 5 minnesceller. Den första cellen används som loopräknare för 10 iterationer, nästa celler innehåller siffrorna 7, 10, 3 och 1 , ökade med denna loop till 70, 100, 30 och 10 , summeringen sker före utskrift, det andra ordet är konstruerad från resterna av den första:
++++++++++ [ > +++++++ > ++++++++++ > +++ > + <<<< - ] > ++ . > + . +++++++ .. +++ . > ++ . << +++++++++++++++ . > . +++ . ------ . -------- . > + . > .Analysera programmet:
Cykeln för att fylla huvudnumren | |
++++++++++ | tilldelar cell 0 värdet 10 |
[ | upprepa kommandona som beskrivs av denna parentes tills värdet för den aktuella cellen 0 inte är lika med noll |
>+++++++ | cellöka 1 gånger 7 |
>++++++++++ | cellöka 2 gånger 10 |
>+++ | cellöka 3 gånger 3 |
>+ | cellöka 4 gånger 1 |
<<<<- | cellminska 0 med 1 |
] | kontrollera om cell 0 är noll |
Utmatning av det första ordet | |
>++. | i cell 1 , lägga till 2 till 70 och skriva ut ASCII-koden 72, dvs. bokstäverna " H ". |
>+. | i cell 2 lägg till 1 till 100 = 101, skriv ut bokstaven " e " |
+++++++.. | i samma cell lägga till 7 till 101 = 108, skriva ut " l " två gånger |
+++. | i samma cell lägger du till 3 till 108 = 111, skriver ut " o " |
>++. | i cell 3 lägg till 2 till 30 = 32, skriv ut ett mellanslag |
Andra ord utdata med cellåteranvändning | |
<<+++++++++++++++. | i cell 1 lägg till 15 till 72 = 87, skriv ut " W " |
>. | cell 2 har redan 111, skriv omedelbart ut " o " |
+++. | i samma cell lägger du till 3 till 111 = 114, skriver ut " r " |
------. | i samma cell, subtrahera 6 från 114 = 108, skriv ut " l " |
--------. | i samma cell, subtrahera 8 från 108 = 100, skriv ut " d " |
>+. | i cell 3 lägg till 1 till 32 = 33, skriv ut " ! » |
>. | cell 4 har redan 10, skriv omedelbart ut radmatning |
Ett exempel på en Brainfuck-tolk skriven i Perl :
#!/usr/bin/perl öppna F , shift ; @code = grep { /[+-\.,\[\]><]/ } split '' , <F> ; för ( my $_ = 0 ; $_ < @code ; ++ $_ ) { ++ $cpu [ $i ] if $code [ $_ ] eq '+' ; -- $cpu [ $i ] om $code [ $_ ] eq '-' ; -- $i if $code [ $_ ] eq '<' ; ++ $i if $code [ $_ ] eq '>' ; skriv ut chr $cpu [ $i ] om $code [ $_ ] eq '.' ; $cpu [ $i ] = ord <STDIN> om $code [ $_ ] eq ',' ; if ( $code [ $_ ] eq '[' ) { if ( ! $cpu [ $i ]) { ++ $brc ; while ( $brc ) { ++ $_ ; ++ $brc if $code [ $_ ] eq '[' ; -- $brc if $code [ $_ ] eq ']' ; } } annat { nästa ; } } elsif ( $kod [ $_ ] eq ']' ) { if ( ! $cpu [ $i ]) { nästa ; } else { ++ $brc if $code [ $_ ] eq ']' ; while ( $brc ) { -- $_ ; -- $brc if $code [ $_ ] eq '[' ; ++ $brc if $code [ $_ ] eq ']' ; } -- $_ ; } } }Ett exempel på en Brainfuck-tolk skriven i C++ :
#include <iostream> #inkludera <fstream> #inkludera <vektor> #inkludera <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 . stäng (); std :: vektor < char > mtape ( 30000 , 0 ); std :: vektor < char >:: iterator m = mtape . börja (); std :: vektor < char >:: iterator i = itape . börja (); int b = 0 ; för (; i != itape . end (); ++ i ) { switch ( * i ){ fall '>' : if ( ++ m == mtape . end ()) { mtape . pushback ( 0 ); m = -mtape . _ slut (); } bryta ; case '<' : -- m ; bryta ; case '+' : ++* m ; bryta ; fall '-' : --* m ; bryta ; fall '.' : std :: cout << * m ; bryta ; case ',' : std :: cin >> * m ; bryta ; fall '[' : if ( * m ) fortsätt ; ++ b ; medan ( b ) switch ( *++ i ){ case '[' : ++ b ; bryta ; fall ']' : - b ; bryta ; } bryta ; fall ']' : om ( !* m ) fortsätt ; ++ b ; medan ( b ) switch ( *-- i ){ case '[' : - b ; bryta ; case ']' : ++ b ; bryta ; } --jag ; _ bryta ; } } }Varje nybörjare som programmerar Brainfuck stöter omedelbart på följande problem:
Dessa problem kan lösas.
Beteckna med @(k) förskjutningen med k celler till höger om k>0, och till vänster om k<0 Följaktligen @(k) = >… k gånger …> eller <… -k gånger …<Brainfuck används nästan aldrig för praktisk programmering (med undantag för enskilda entusiasters arbete), och används främst för pussel och tävlingsproblem.
Anmärkningar: 1. Speciellt för funktionaliteten av mOO-kommandot, introduceras de interna koderna för dess kommandon [2] i COW-språket , i tabellen anges de i en separat kolumn. 2. Frånvaron av ett lag indikeras som frånvarande .
Brainfuck | Ok! | KO | COW-kod | Beskrivning |
] | Ok? Ok! | mu | 0 | Slut på cykeln |
< | Ok? OK. | mu | ett | Föregående cell |
> | OK. Ok? | mu | 2 | Nästa cell |
ots. | ots. | mu | 3 | Utför värdet i den aktuella cellen som ett kommando med motsvarande kod från intervallet 0 - 11; kod 3 orsakar en loop |
ots. | ots. | Mu | fyra | Om värdet på den aktuella cellen är noll, skriv in det från tangentbordet; om värdet på den aktuella cellen inte är noll, visa det på skärmen |
- | Ok! Ok! | Mu | 5 | Värdet på den aktuella cellen minskas med 1 |
+ | OK. OK. | Mu | 6 | Värdet på den aktuella cellen ökas med 1 |
[ | Ok! Ok? | MO | 7 | Loopstart (COW har en funktion - det första kommandot i loopen hoppas över) |
[-] | ots. | OOO | åtta | Återställer värdet i den aktuella cellen |
ots. | ots. | MMM | 9 | Om registret är tomt, kopiera värdet av den aktuella cellen in i det, annars kopiera innehållet i registret till cellen och rensa registret |
. | Ok! OK. | OOM | tio | Visar värdet för den aktuella cellen |
, | OK. Ok! | oom | elva | Fråga värdet för den aktuella cellen |
En annan beskrivning av de många dialekterna i detta språk finns i wikiuppslagsverket över esoteriska språk [3]
Programmeringsspråk | |
---|---|
|