Brainfuck

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 20 juni 2022; kontroller kräver 7 redigeringar .
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).

Programexempel

Brainfuck steg-för-steg-program som skriver ut Hello World! » med en radbrytning (i form av en ASCII-kod - 72 101 108 108 111 32 87 111 114 108 100 33 10): ++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ . +++++++++++++++++ ++++++++++++ . +++++++ .. +++ . -------------------- -------------------------------------------------- -- --------------- . +++++++++++++++++++++++++++++ +++++++++++++++++++++++++++ . ++++++++++++++++++++ ++++++ . +++ . ------ . -------- . ------------------ -------------------------------------------------- -- ---- . ---------------------------- .

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

Brainfuck tolk

Perl

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 ']' ; } -- $_ ; } } }

C++

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 ; } } }

Brainfuck programmering

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 …<
noll(): nollställer den aktuella cellen: [-] = [+]
add(k): adderar värdet av cell n (nuvarande) till värdet av cell n+k: [ - @(k) + @(-k) ] i detta fall förloras värdet på cell n (nollställs).
mov(k): kopiering av värdet av cell n (nuvarande) till cell n+k med förlusten (nollställning) av värdet på cell n: @(k) noll() @(-k) add(k) = @(k) [-] @(-k) [ - @(k) + @(-k) ]
copy(k,t): kopiera värdet av cell n (nuvarande) till cell n+k med användning av en mellancell n + k + t, på grund av vilken värdet på cell n inte förloras (sparas). @(k) noll() @(t) noll() @(-kt) [ - @(k) + @(t) + @(-kt) ] @(k+t) mov(-kt) = @(k) [-] @(t) [-] @(-kt) [ — @(k) + @(t) + @(-kt) ] @(k+t) [ — @(-kt) + @(k+t) ]
ifelse(t): om aktuell cell>0 så sant om den aktuella cellen = 0, är ​​villkoret falskt t-relativt hjälpcellsnummer: @(t)[-]+@(-t) sätt flagga 1 för annat fall [ här gren handlingar sant @(t)[-]@(-t) sätt flaggan 0 för annat fall [-] loop utgång ] @(t) [@(-t) här grenåtgärder falska @(t)[-] loop utgång ] @(-t-1)

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.

Brainfuck-baserade språk

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

Se även

Dialekter och realiseringar

En annan beskrivning av de många dialekterna i detta språk finns i wikiuppslagsverket över esoteriska språk [3]

Andra abstrakta implementerare och formella datorsystem

Anteckningar

  1. Till exempel, 166 byte kompilatorkälla (länk ej tillgänglig) . Tillträdesdatum: 18 augusti 2010. Arkiverad från originalet 19 augusti 2010. 
  2. COW - en dialekt av programmeringsspråket Brainfuck - Encyclopedia of Programming Languages . Hämtad 11 december 2020. Arkiverad från originalet 5 maj 2021.
  3. Kategori:Brainfuck_derivatives Arkiverad 14 april 2012 på Wayback Machine , esolangs.org

Länkar